Hi,
I'm wanting to simply read the serial output from the Arduino Uno using Perl.
I've followed the playground code (Arduino Playground - PERL), which only changing to use Win32 (I'm using 64bit Windows 7, ActiveState Perl v5.16.3).
# Set up the serial port
use Win32::SerialPort;
my $port = Win32::SerialPort->new("COM30");
$port->is_rs232;
# 9600, 81N on the USB ftdi driver
$port->baudrate(9600); # you may change this value
$port->databits(8); # but not this and the two following
$port->parity("none");
$port->stopbits(1);
$port->write_settings();
print "Start\n";
# now catch gremlins at start
my $tEnd = time()+2; # 2 seconds in future
while (time()< $tEnd) { # end latest after 2 seconds
my $c = $port->lookfor(); # char or nothing
next if $c eq ""; # restart if noting
# print $c; # uncomment if you want to see the gremlin
last;
}
print "step 1\n";
while (1) { # and all the rest of the gremlins as they come in one piece
my $c = $port->lookfor(); # get the next one
last if $c eq ""; # or we're done
# print $c; # uncomment if you want to see the gremlin
}
print "step 2\n";
while (1) {
# Poll to see if any data is coming in
my $char = $port->lookfor();
# If we get data, then print it
# Send a number to the arduino
if ($char) {
print "Received character: $char \n";
}
# Uncomment the following lines, for slower reading,
# but lower CPU usage, and to avoid
# buffer overflow due to sleep function.
# $port->lookclear;
# sleep (1);
}
The script just never receives/prints any data from the Arduino... It gets to 'step 2', and that is the last print from Perl.
For testing, I'm just using the Arduino AnalogReadSerial example:
/*
AnalogReadSerial
Reads an analog input on pin 0, prints the result to the serial monitor.
Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.
This example code is in the public domain.
*/
// the setup routine runs once when you press reset:
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
}
// the loop routine runs over and over again forever:
void loop() {
// read the input on analog pin 0:
int sensorValue = analogRead(A0);
// print out the value you read:
Serial.println(sensorValue);
delay(1); // delay in between reads for stability
}
Anyone have a working example for Windows/ActiveState, or can help please?
I tried changing the delay - no effect.
The script shouldn't have a problem reading a fast serial input, and 9600 is pretty slow.
I'm pretty new with Perl. I think the issue is with using Win32::SerialPort, as the code is otherwise basically the exact same as playground code (which I presume works).
Joshua2014:
I tried changing the delay - no effect.
The script shouldn't have a problem reading a fast serial input, and 9600 is pretty slow.
I'm pretty new with Perl. I think the issue is with using Win32::SerialPort, as the code is otherwise basically the exact same as playground code (which I presume works).
The problem is that the Arduino cannot send it as fast as you are trying to so whatever emerges from the Arduino would probably be garbage.
Joshua2014:
Robin, the Arduino code is the example in the Arduino IDE - and works fine, delay(1) or delay(1000).
Interesting. I didn't think it would. Presumably it will also work without any delay().
Can you explain exactly what the different parts of the Perl code are trying to do? The word "gremlins" is not very informative. Have you got it to print them?
If it gets as far as Step 2 something must be working.
However this code is intended for a Linux box (/dev/tty.usbserial), so I've made only a couple changes:
Use Win32::SerialPort instead of Device::SerialPort.
Use "COM30" instead of "/dev/tty/usbserial".
Use 9600baud instead of 19200.
So that the port settings take affect, added: $port->write_settings();
No gremlins are printed. Yes, it gets to Step 2, so the code is syntactically fine. But something is obviously not working as desired.
My problem is that I don't know Perl and I'm assuming you do - hence my request that you explain it. If I understand what it is trying to do I may be able to see where the problem is.
There seem to be some commented out lines that can be un-commented to print the gremlins. Have you tried that?
Have you some way to verify that COM30 is correct?
CreateFile() is successful when you use "COM1" through "COM9" for the name of the file; however, the message INVALID_HANDLE_VALUE is returned if you use "COM10" or greater.