Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sp.gets working in irb, but not as ruby script #57

Open
s2tephen opened this issue Nov 13, 2014 · 3 comments
Open

sp.gets working in irb, but not as ruby script #57

s2tephen opened this issue Nov 13, 2014 · 3 comments

Comments

@s2tephen
Copy link

I am trying to set up serial communication between a Ruby on Rails app and an Arduino Mega. In Ruby, I am writing an array of strings to the serial, which the Arduino is then supposed to read, process and write corresponding output back to the serial.

For some reason, when I use irb and run the script line by line, everything works and I get the desired result, but when I use ruby sample.rb or run the code from inside Rails, it just gets stuck in the while loop and never returns anything. Would love any guidance on how to get this working.

# sample.rb
require 'serialport'

port_str = '/dev/tty.usbmodem1411'
baud_rate = 9600
data_bits = 8
stop_bits = 1
parity = SerialPort::NONE

sp = SerialPort.new(port_str, baud_rate, data_bits, stop_bits, parity)

seq = ['[h:0,0,120,5]', '[t:0,1,6,7,4]', '[t:-1,2,5,-1,3]', '[t:-1,0,2,-1,-1]', '[l:1,1,0.5,0.5,1]']

seq.each do |i|
  puts 'laptop> ' + i
  sp.write i
end

while(true)
  while (o = sp.gets.chomp) do
    puts 'arduino> ' + o
  end
end

For reference, I am running Ruby 2.1.2, Rails 4.1.4, and serialport 1.3.1.

@s2tephen
Copy link
Author

Update: with some desperation tweaks (I added sp.flush and sleep between the write/read blocks), I am now able to get the code somewhat working in Rails. It doesn't seem to work 100% of the time, though, will need to do some further testing.

seq.each do |i|
      puts 'laptop> ' + i
      sp.write i
    end

    sp.flush
    sleep 3

    while (o = sp.gets.chomp) do
      puts 'arduino> '+ o
      if o == 'done'
        break
      end
    end

@schrockwell
Copy link

@s2tephen: I would recommend breaking out your read operations into a separate thread. Join it to the main thread when you're done.

Something like this (untested):

require 'thread'

read_thread = Thread.new do
  while (o = sp.gets.chomp) do
    puts 'arduino> '+ o
    if o == 'done'
      break
    end
  end
end

seq.each do |i|
  puts 'laptop> ' + i
  sp.write i
end

read_thread.join

@noniq
Copy link

noniq commented Jun 5, 2015

This problem seems to be caused by the “auto reset on serial connection” feature of Arduino boards: Everytime a serial connection is opened, the board resets itself. Thus you need to wait a few seconds before you can start sending / receiving data.

See http://playground.arduino.cc/Main/DisablingAutoResetOnSerialConnection for more info.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants