• Welcome to PiBoSo Official Forum. Please login or sign up.
 
March 28, 2024, 04:24:26 PM

News:

GP Bikes beta21c available! :)


Send values via USB to arduino??

Started by Antian, August 26, 2020, 03:13:00 PM

Previous topic - Next topic

Antian

Anyone have a good way of sending values (lets say m_fRoll) to arduino via USB and not udp?
I've tried using example codes but does not establish connection (com port 3 in my case).
Right now I'm simply trying to establish connection and send test data, so code is simplistic.
I've attached the C_code and Arduino test code. Any help very much appreciated.

The error I receive is 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 arduino. 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.

h106frp

August 26, 2020, 03:24:54 PM #1 Last Edit: August 26, 2020, 03:27:02 PM by h106frp
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).

By far the easiest way is a generic network board for ARDUINO (about £5) and use UDP

Antian

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).

h106frp

August 26, 2020, 03:53:59 PM #3 Last Edit: August 26, 2020, 04:27:43 PM by h106frp
This is a good link for understanding USB https://www.waitingforfriday.com/?p=451

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

A quick read and the base model ARDUINO use an FTDI chip to emulate a classic COM port - they do not have USB unless you get an add on board. So you should just be able to open the port and talk back and forth across the Arduino virtual COM port.

The createfile call looks OK, I would remove all the remarks just in case though
hComm = CreateFile("\\\\.\\COM3",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);

 - can you confirm the virtual COM port driver is installed as COM3?

Antian

From what I can tell the all the drivers are installed and windows shows the device connected to COM3. If I unplug it, the "COM3" disappears. If thats what you mean.
I've used this device to even make a joystick that works with GPB, and everything runs fine that way. I have two of these boards and testing output data on one of them.(trying to)
FYI to be specific this is a teensy 3.2
Appreciate the help/info

h106frp

August 26, 2020, 06:15:10 PM #5 Last Edit: August 26, 2020, 06:18:50 PM by h106frp
You could try this slighly differnt call https://support.microsoft.com/en-us/help/115831/howto-specify-serial-ports-larger-than-com9

I am wondering, that if you have the ARDUINO environment open at the same time has it already reserved COM3 for its (exclusive) use?

You can download and run the old hperterminal from windows XP to test serial comms on win7 and later
https://www.instructables.com/id/Port-Hyperterminal-to-Windows-7/

Antian

The device default is COM3.
From my understanding is anything higher than COM9 requires the use of \ like (\\\\.\\COM10) anything less is just (COM#). I've used both with and without \'s no effect.
I can assign the device a different COM port to say 10,12,23.etc. and change my code to match but still no effect.
If the arduino serial monitor is open then it does cause in interrupt with connection, so I keep it closed.
I see this happen when using CreateFileA command stated earlier, which tells me its making some kind of COM connection(it sees the device).
My guess at this point would be there's a problem with how I'm telling it to send the data, or how I'm telling teensy to receive said data. All the tutorials I find and try to use end with same result. I'm trying to get help from the people over at teensy too.
I appreciate your time on this though H.

h106frp

Serial is pretty dumb, so when you open the port it will only look at the PC (host) end.

Worth trying hyperterminal to check that it can open the port OK and send some data. It will basically run stand-alone from the directory without any install.

If you try it, in the options set it to echo send and receive and you should be able to see all the data

Antian

:o  OK. so I tried hyperterminal and it read back the Serial.write function... "Value Read %d" ....of the teensy and the light started blinking as I instructed it to do (simple but hey). It was showing garbage when I typed for some reason and no returning data being sent back.
Though I still don't know if It's an error in the C code sending the data or what?
So the problem is I can't code  :-[
I was trying to keep it real simple.

h106frp

Not a studio expert so this is a bit desperate but should you have (for classic c);

#include <windows.h>

and

HANDLE hComm;

at the start of the code?

Antian

#include <windows.h> & HANDLE is there (though not on the file I posted, sorry) without it would not compile.

h106frp

August 26, 2020, 10:34:20 PM #11 Last Edit: August 26, 2020, 10:42:46 PM by h106frp
Cannot be much wrong with your code; installed code::blocks and GNU compiler and it worked fine opening the port to my arduino using;

// Open serial port
HANDLE hComm;
hComm = CreateFile("\\\\.\\COM9", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

I have devices on COM5 and COM9 and it worked for both

If you want to try something other than studio;
http://www.codeblocks.org/downloads/binaries

you want; codeblocks-20.03mingw-setup.exe

go to settings>compiler>

for GNU GCC compiler go to 'toolchain executables' tab and auto detect path to load in the compiler module

Good to go..

Antian

August 26, 2020, 10:49:53 PM #12 Last Edit: August 26, 2020, 10:51:29 PM by Antian
Appreciate that H.
Which arduino model you using? May just buy that.
and I'll try code blocks just in case... I've use code blocks in the past some too. I'd be shocked if it was that.
Also do you mind sharing what arduino test code you used? In case I'm missing something.

h106frp

Its a cheap generic MEGA2560, driver states USB-SERIAL CH340,
 also opened the port to my EDTracker, driver states Arduino Leonardo (was another cheap generic board)

This was just a very quick fudge to see if the ports would open OK..
#include <iostream>
#include <windows.h>
using namespace std;

int main()
{
    cout << "Hello world!" << endl;


    // Open serial port
HANDLE hComm;
hComm = CreateFile("\\\\.\\COM9", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

if (hComm == INVALID_HANDLE_VALUE) {
printf_s("\nSerial port failed\n");
cout << "Fail" << endl;
}
else {
printf_s("\nSerial port successful\n");
        cout << "Port open" << endl;
}
DCB dcbSerialParams = { 0 }; // Initializing DCB structure
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);

//Status = GetCommState(hComm, &dcbSerialParams);

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

//Status = SetCommState(hComm, &dcbSerialParams);

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
CloseHandle(hComm);
    return 0;
}

Antian

Hey everyone,
So while I'm researching the best way to send values over COM port to arduino,
thought I'd post this in case someone could stop me from digging too far into the wrong direction.
FYI codes below may not be typed up correctly... just throwing something up for talking points.

the writefile function expects char* value. So I need to convert int/float to char then send to arduino.
Arduino then receives and convert char back to int/float.
One example.
char* int2str(unsigned long num) {
static char retnum[21];
sprintf(retnum, "%ul", num)
return retnum;
}
Also have to write one for float conversion.

I read that using binary conversion is the best option, but only *IF* you know what you're doing,
and ascii is the easiest method but with overhead on the system (slower) or there's hex.
I'm not experienced so guess I'll go ascii.

So if I want to send an int... lets say m_iRPM and a float m_fSpeedometer or multiple values per loop, then I guess use a variable array such as:
float num [2][2];
num[0]= int(p->m_sData.m_iRPM);
num[1] = p->m_sData.m_fSpeedometer;

char* float2str(){
do some conversion;
return result;
}

float2str (num);

WriteFile(hFile,
float2str,
sizeof(float2str),
NULL,
NULL);

This sends char to arduino which then gets reversed back to respective values....??

Have not tried this... I'm just looking into possible options.
Am I even close to being on right path??
Thanks