... can't open device: \.\COM22 ...
Notice the leading single backslash in the error message where a double backslash was advised. Even in single quoted strings, backslash interpolation is tricky:
c:\@Work\Perl\monks>perl -wMstrict -le
"my $s = 'A: \\.\COM22';
print qq{'$s'};
;;
$s = 'B: \\\.\COM22';
print qq{'$s'};
"
'A: \.\COM22'
'B: \\.\COM22'
Give a man a fish: <%-(-(-(-<
| [reply] [Watch: Dir/Any] [d/l] [select] |
Are you sure that you handled the backslashes properly? The port name for COM22 is \\.\COM22, but your error message complains about \.\COM22. If you used double-quotes, then you would need to have it like this "\\\\.\\COM22".
| [reply] [Watch: Dir/Any] |
| [reply] [Watch: Dir/Any] |
It's been quite a while since I have used Win32::SerialPort. Also, I don't have an arduino device to test code against.
Here's the approach that I would take to debug the issues. (NOTE: I'm not guaranteeing that this will help solve the issue. This is just how I would approach the debug process.)
- First, use something like putty to connect to the device and try issuing commands. This will help verify that you have the correct connection settings (baud rate, parity, handshake, etc.). This also would help to verify that you can send commands and get the expected response from the device. In other words, do it outside of Perl and if you can't get that to work, then your code will be wrong too.
- Check to make sure that you are actually connecting to the device. Although, you do have a die statement on the Win32::SerialPort object creation, you're not really printing out anything useful if there is a problem. Look at the Constructors section of the Win32::SerialPort documentation for examples of how to do this. If your code isn't able to connect, then the rest of it isn't going to work either. Even if your current code is connecting, I would still recommend modifying your die statement to include more useful information. It's just a good habit to get into.
- In your posted code, I see back to back write statements where you are issuing commands, but I don't see any reads where you read the response back from the device. Part of me is wondering if that may be part of the problem.
- In your config.pl, you have use Win32::SerialPort; and in your serial.pl you have use Win32::SerialPort 0.11;. If you're intending to use these scripts together, I'm not sure why you wouldn't want these two use statements to be the same. Also, the latest version of Win32::SerialPort is version 0.22. I'm wondering if you were to update your Win32::SerialPort module if that might help. See here for list of changes/updates. In your case, you could benefit from that fact that version 0.20 added better support for COM ports 10 and above.
- I'm also wondering if there might be a timing issue - even though you have already tried adding sleep statements. I had run into this type of issue before. First, look through the device's documentation to see if there is any information about response time to commands. Next, take a look at the Configuration and Capability Methods section of the Win32::SerialPort documentation and in particular, thoroughly read through the subsection on "Timeouts". That section explains how to calculate the time needed to do reads and writes. And four of those elements (read_const_time, read_char_time, write_const_time, write_char_time) can be set by your code. I don't remember all of the details, but in my case, it took me a while to get my head wrapped around what that section of the documentation was explaining and by making changes to one or more of those elements, I was able to fix the timing issue in my code.
I'm not going to claim that the information above will definitely fix your issue(s) with your code, but based on my past experience with using Win32::SerialPort to communicate with a device, that's where I would start with the debug process.
| [reply] [Watch: Dir/Any] [d/l] [select] |