I'm facing what seems to be a very odd issue. I've very much simplified my sketch and Ruby code in order to isolate the problem.
Ruby version is 2.0.0, and ruby-serialport version is 2.3.0. I'm on Mac OS X 10.9 (Mavericks).
Here is my sketch. As you can see, it just lights up pin 13 for 500ms if it receives ANY serial data.
serialtest.ino
void setup(){
Serial.begin(115200);
pinMode(13, OUTPUT);
}
void loop(){
while(Serial.available()){
byte x = Serial.read();
digitalWrite(13, HIGH);
delay(500);
digitalWrite(13, LOW);
delay(500);
}
}
And here is my Ruby code.
serialtest.rb
require 'serialport'
# This is the correct port file, don't worry
sp = SerialPort.new('/dev/tty.usbmodem411', 115200)
sp.write "a"
sp.flush
This code, if run by itself, does NOT work. There aren't any exceptions or warnings displayed, but the LED on pin 13 does not light up (even though the RX light on the Arduino does flash briefly). However, running serialtest.rb
under the following conditions works:
If I open IRB and run
SerialPort.new('/dev/tty.usbmodem411', 115200)
and leave IRB open. The moment I close IRB, however, runningserialtest.rb
no longer makes pin 13 light up.If I open up Arduino's serial monitor and leave it open. As soon as I close it, again, light 13 stops lighting up when running
serialtest.rb
.If I type the entire thing into IRB. But it has to be line-by-line. If I copy-and-paste it, pin 13 does not light up (in this case, I don't have to run
serialtest.rb
).
It's just very odd. I thought that this question would resolve the issue, but it has not (as you can see I have put sp.flush
at the end of the file. I have also tried putting it in the beginning of the file, and everywhere in between. I have also tried setting sp.sync = true
right after opening the connection, and that doesn't work either). Neither does calling sp.syswrite
, which is supposed to be unbuffered. The only thing that works seems to be having another process open the serial connection.
It just seems that serialport is unable to actually establish a connection from within a file, and must have it done externally (copying the SerialPort.new(...)
code into the inside of Thread.new
didn't work either).
Any help would be greatly appreciated.
Edit: It seems that the issue stemmed from the fact that the Arduino was reset every time Ruby attempted to establish a serial connection (whereas IRB and the serial monitor held the connection open, causing the SerialPort.new
call in serialtest.rb
to be ignored). Ultimately, my solution was putting a 10uF capacitor between RESET and GND on the Arduino.