22
33Arduino::~Arduino ()
44{
5- if (m_arduinoHandle != INVALID_HANDLE_VALUE )
5+ if (handle != INVALID_HANDLE_VALUE )
66 {
7- CloseHandle (m_arduinoHandle);
7+ CloseHandle (handle);
8+ LOG (" Disconnected from Arduino." );
89 }
910}
1011
11- Arduino::Arduino (LPCSTR device_name ) : m_arduinoHandle (INVALID_HANDLE_VALUE )
12+ Arduino::Arduino (LPCSTR name ) : handle (INVALID_HANDLE_VALUE )
1213{
1314 char port[100 ] = " \\ .\\ " ;
1415
15- while (!GetDevice (device_name, port))
16+ LOG (" Searching for device..." );
17+ while (!GetDevice (name, port))
1618 {
19+ LOG (" Device not found. Retrying..." );
1720 sleep_for (milliseconds (1000 ));
1821 }
1922
20- this ->m_arduinoHandle = CreateFile (port, GENERIC_READ | GENERIC_WRITE , 0 , NULL , OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL );
21- if (this ->m_arduinoHandle )
23+ LOG (string (" Device found: " ) + name + " (" + port + " )" );
24+
25+ handle = CreateFile (port, GENERIC_READ | GENERIC_WRITE , 0 , nullptr , OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , nullptr );
26+
27+ if (handle == INVALID_HANDLE_VALUE )
2228 {
23- DCB dcb = { 0 };
24- dcb.DCBlength = sizeof (dcb);
25- if (!GetCommState (this ->m_arduinoHandle , &dcb))
26- {
27- printf (" GetCommState() failed\n " );
28- CloseHandle (this ->m_arduinoHandle );
29- }
29+ DWORD error_code = GetLastError ();
30+ LOG (" Error opening port: " + to_string (error_code));
31+ cerr << " Error opening port: " << error_code << endl;
32+ return ;
33+ }
3034
31- dcb.BaudRate = CBR_9600 ;
32- dcb.ByteSize = 8 ;
33- dcb.StopBits = ONESTOPBIT ;
34- dcb.Parity = NOPARITY ;
35- if (!SetCommState (this ->m_arduinoHandle , &dcb))
36- {
37- printf (" SetCommState() failed\n " );
38- CloseHandle (this ->m_arduinoHandle );
39- }
35+ LOG (" Port opened successfully." );
4036
41- COMMTIMEOUTS cto = { 0 };
42- cto.ReadIntervalTimeout = 50 ;
43- cto.ReadTotalTimeoutConstant = 50 ;
44- cto.ReadTotalTimeoutMultiplier = 10 ;
45- cto.WriteTotalTimeoutConstant = 50 ;
46- cto.WriteTotalTimeoutMultiplier = 10 ;
47- if (!SetCommTimeouts (this ->m_arduinoHandle , &cto))
48- {
49- printf (" SetCommTimeouts() failed\n " );
50- CloseHandle (this ->m_arduinoHandle );
51- }
52- cout << " Successfully connected!" << endl;
37+ DCB dcb = {};
38+ dcb.DCBlength = sizeof (dcb);
39+
40+ if (!GetCommState (handle, &dcb))
41+ {
42+ LOG (" Failed to get port state." );
43+ return ;
44+ }
45+
46+ dcb.BaudRate = CBR_9600 ;
47+ dcb.ByteSize = 8 ;
48+ dcb.StopBits = ONESTOPBIT ;
49+ dcb.Parity = NOPARITY ;
50+
51+ if (!SetCommState (handle, &dcb))
52+ {
53+ LOG (" Failed to set port state." );
54+ return ;
5355 }
56+
57+ COMMTIMEOUTS cto = {};
58+ cto.ReadIntervalTimeout = 50 ;
59+ cto.ReadTotalTimeoutConstant = 100 ;
60+ cto.ReadTotalTimeoutMultiplier = 10 ;
61+ cto.WriteTotalTimeoutConstant = 50 ;
62+ cto.WriteTotalTimeoutMultiplier = 10 ;
63+
64+ if (!SetCommTimeouts (handle, &cto))
65+ {
66+ LOG (" Failed to set timeouts." );
67+ return ;
68+ }
69+
70+ LOG (" Port initialized successfully." );
71+ cout << " Successfully connected!" << endl;
5472}
5573
5674bool Arduino::IsAvailable () const
5775{
5876 DWORD errors;
5977 COMSTAT status;
6078
61- if (!ClearCommError (m_arduinoHandle , &errors, &status))
79+ if (!ClearCommError (handle , &errors, &status))
6280 {
63- cerr << " Error checking available data: " << GetLastError () << endl ;
81+ LOG ( " Error checking available data: " + to_string ( GetLastError ())) ;
6482 return false ;
6583 }
6684
6785 return status.cbInQue > 0 ;
6886}
6987
70- bool Arduino::GetDevice (LPCSTR friendly_name , LPSTR com_port )
88+ bool Arduino::GetDevice (LPCSTR name , LPSTR port )
7189{
72- char com[] = " COM" ;
7390 bool status = false ;
74-
7591 HDEVINFO device_info = SetupDiGetClassDevs (&GUID_DEVCLASS_PORTS , NULL , NULL , DIGCF_PRESENT );
76- if (device_info == INVALID_HANDLE_VALUE ) return false ;
7792
78- SP_DEVINFO_DATA dev_info_data;
79- dev_info_data.cbSize = sizeof (dev_info_data);
93+ if (device_info == INVALID_HANDLE_VALUE )
94+ {
95+ LOG (" Failed to get device information." );
96+ return false ;
97+ }
8098
8199 DWORD count = 0 ;
100+ SP_DEVINFO_DATA dev_info_data = {};
101+ dev_info_data.cbSize = sizeof (dev_info_data);
102+ LOG (" Searching for device: " + string (name));
103+
104+ struct DeviceInfo
105+ {
106+ string port;
107+ string hardware_id;
108+ string friendly_name;
109+ };
82110
111+ vector<DeviceInfo> devices;
112+ vector<regex> patterns = { regex (" VID_2341&PID_.*" ), regex (" VID_1A86&PID_.*" ), regex (" VID_10C4&PID_.*" ) };
113+
114+ // Step 1: Collecting all devices
83115 while (SetupDiEnumDeviceInfo (device_info, count++, &dev_info_data))
84116 {
117+ DeviceInfo info;
85118 BYTE buffer[256 ];
119+
120+ // Reading FRIENDLYNAME
86121 if (SetupDiGetDeviceRegistryProperty (device_info, &dev_info_data, SPDRP_FRIENDLYNAME , NULL , buffer, sizeof (buffer), NULL ))
87122 {
88- DWORD i = strlen (com_port);
89- LPCSTR lp_pos = strstr ((LPCSTR )buffer, com);
90- DWORD len = i + (lp_pos ? strlen (lp_pos) : 0 );
123+ info.friendly_name = string ((LPCSTR )buffer);
124+ LOG (" Device detected with FRIENDLYNAME: " + info.friendly_name );
125+
126+ // Reading PORT
127+ LPCSTR start = strchr ((LPCSTR )buffer, ' (' );
128+ LPCSTR end = strchr ((LPCSTR )buffer, ' )' );
91129
92- if (strstr (( LPCSTR )buffer, friendly_name) && lp_pos )
130+ if (start && end && end > start )
93131 {
94- for (DWORD j = 0 ; i < len; i++, j++)
95- {
96- com_port[i] = lp_pos[j];
97- }
132+ info.port = string (start + 1 , end - start - 1 );
133+ }
134+ }
135+
136+ // Reading HARDWAREID
137+ if (SetupDiGetDeviceRegistryProperty (device_info, &dev_info_data, SPDRP_HARDWAREID , NULL , buffer, sizeof (buffer), NULL ))
138+ {
139+ info.hardware_id = string ((LPCSTR )buffer);
140+ LOG (" Device detected with HARDWAREID: " + info.hardware_id );
141+ }
142+
143+ devices.push_back (info);
144+ }
145+
146+ SetupDiDestroyDeviceInfoList (device_info);
147+
148+ // Step 2: Checking and selecting the device
149+ for (const auto & device : devices)
150+ {
151+ LOG (" Evaluating device: FRIENDLYNAME = " + device.friendly_name + " , HARDWAREID = " + device.hardware_id );
152+
153+ // If the name is specified, check it
154+ if (name && !device.friendly_name .empty () && device.friendly_name .find (name) != string::npos)
155+ {
156+ strncpy_s (port, 100 , device.port .c_str (), device.port .size ());
157+ LOG (" Device matched by FRIENDLYNAME: " + device.friendly_name );
158+ status = true ;
159+ break ;
160+ }
98161
99- com_port[i - 1 ] = ' \0 ' ;
162+ // If the name does not match, check the VID/PID
163+ for (const auto & pattern : patterns)
164+ {
165+ if (!device.hardware_id .empty () && regex_search (device.hardware_id , pattern))
166+ {
167+ strncpy_s (port, 100 , device.port .c_str (), device.port .size ());
168+ LOG (" Device matched by VID/PID: " + device.hardware_id );
100169 status = true ;
101170 break ;
102171 }
103172 }
173+
174+ if (status) break ;
175+ }
176+
177+ if (!status)
178+ {
179+ LOG (" No matching device found." );
104180 }
105181
106- SetupDiDestroyDeviceInfoList (device_info);
107182 return status;
108183}
109184
110185bool Arduino::WriteMessage (const string& message) const
111186{
112- DWORD bw = 0 ;
113- BOOL result = WriteFile (m_arduinoHandle , message.c_str (), message.size () + 1 , &bw , nullptr );
187+ DWORD bytes = 0 ;
188+ BOOL result = WriteFile (handle , message.c_str (), message.size () + 1 , &bytes , nullptr );
114189
115- if (result == 0 || bw != message.size () + 1 )
190+ if (result == 0 || bytes != message.size () + 1 )
116191 {
192+ LOG (" Failed to send message: " + message);
117193 cerr << " Failed to send message!" << endl;
118194 return false ;
119195 }
120196
197+ LOG (" Message sent: " + message);
121198 return true ;
122199}
123200
124- string Arduino::ReceiveMessage ( char delimiter) const
201+ void Arduino::LogMessage ( const string& message)
125202{
126- string result;
127- char buffer[256 ];
128- DWORD bytesRead = 0 ;
203+ static ofstream log_file (" arduino_debug.log" , ios::app);
129204
130- while ( this -> IsAvailable ())
205+ if (!log_file. is_open ())
131206 {
132- memset (buffer, 0 , sizeof (buffer));
133-
134- if (!ReadFile (m_arduinoHandle, buffer, sizeof (buffer), &bytesRead, nullptr ))
135- break ;
207+ cerr << " Error opening the log file." << endl;
208+ return ;
209+ }
136210
137- for (DWORD i = 0 ; i < bytesRead; i++)
138- {
139- if (buffer[i] == delimiter)
140- {
141- return result;
142- }
211+ tm local;
212+ time_t now = time (nullptr );
213+ localtime_s (&local, &now);
143214
144- result += buffer[i];
145- }
146- }
215+ char buffer[100 ];
216+ strftime (buffer, sizeof (buffer), " %Y-%m-%d %H:%M:%S" , &local);
147217
148- return result ;
218+ log_file << " [ " << buffer << " ] " << message << std::endl ;
149219}
0 commit comments