Class: Win32::Serial

Inherits:
Object
  • Object
show all
Defined in:
lib/serial/win32.rb

Instance Method Summary collapse

Constructor Details

#initialize(port) ⇒ Serial



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/serial/win32.rb', line 19

def initialize(port)
  @read_buffer = ""

  @CreateFile = Win32API.new('Kernel32', 'CreateFile', 'PLLLLLL', 'L')
  @CloseHandle = Win32API.new('Kernel32','CloseHandle', 'L', 'N')
  @ReadFile = Win32API.new('Kernel32','ReadFile','LPLPP','I')
  @WriteFile = Win32API.new('Kernel32','WriteFile','LPLPP','I')
  @SetCommState = Win32API.new('Kernel32','SetCommState','LP','N')
  @SetCommTimeouts = Win32API.new('Kernel32','SetCommTimeouts','LP','N')
  @BuildCommDCB = Win32API.new('Kernel32','BuildCommDCB', 'PP', 'N')
  @GetLastError = Win32API.new('Kernel32','GetLastError', 'V', 'N')

  # Open the device non-overlapped
  @device = create_file(port, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL)

  # Set the speed
  set_comm_state(9600, 8, 'N', 1)

  # Need to be able to reset blocking
  set_comm_timeouts(2, 1, 1, 0, 0)
end

Instance Method Details

#closeObject



86
87
88
89
90
# File 'lib/serial/win32.rb', line 86

def close
  hResult = @CloseHandle.call(@device) if @device
  raise "Could not close device (#{get_last_error})" if hResult == 0
  @device = nil
end

#finalizeObject



41
42
43
# File 'lib/serial/win32.rb', line 41

def finalize
  close 
end

#readObject



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/serial/win32.rb', line 45

def read
  Timeout::timeout(60) do
    begin
      count = " "*4
      buffer = " "*1024
      hResult = @ReadFile.Call(@device, buffer, 1024, count, NULL)
      raise "Could not read data (#{get_last_error})" if hResult == 0
      count = count.unpack("L").first
      @read_buffer << buffer[0..(count-1)]
      hResult
    rescue Timeout::Error
      puts "Timed out reading"
    end  
  end
end

#read_until(term) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/serial/win32.rb', line 61

def read_until(term)
  Timeout::timeout(60) do
    begin
      term = [term].flatten
      stop = nil
      loop do
        term.each {|t| stop = t and break if @read_buffer.index(t)}
        break if stop
        read
      end
      @read_buffer.slice!(0, @read_buffer.index(stop)+stop.size)
    rescue Timeout::Error
      puts "Timed out reading until '#{term}'"
    end
  end
end

#write(data) ⇒ Object



78
79
80
81
82
83
84
# File 'lib/serial/win32.rb', line 78

def write(data)
  count = " "*4
  hResult = @WriteFile.Call(@device, data, data.size, count, NULL)
  count = count.unpack("L").first
  raise "Could not write data (#{get_last_error})" if hResult == 0
  # raise "Not enough bytes written" if count != data.size
end