digiusb 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/digiterm +5 -2
- data/lib/digiusb.rb +74 -13
- metadata +1 -1
data/bin/digiterm
CHANGED
@@ -11,7 +11,6 @@ spark = DigiUSB.sparks.last
|
|
11
11
|
|
12
12
|
puts "Attached to #{spark.inspect.green}".blue
|
13
13
|
puts "Type control + c to exit".blue
|
14
|
-
|
15
14
|
begin
|
16
15
|
loop do
|
17
16
|
char = spark.getc
|
@@ -29,7 +28,11 @@ begin
|
|
29
28
|
end
|
30
29
|
rescue LIBUSB::ERROR_PIPE, LIBUSB::ERROR_NO_DEVICE
|
31
30
|
puts "" # newline
|
32
|
-
puts "Digispark disconnected
|
31
|
+
puts "Digispark disconnected".white_on_red
|
32
|
+
rescue DigiUSB::ErrorCrashed
|
33
|
+
puts "" # newline
|
34
|
+
puts "Digispark has crashed".white_on_red
|
35
|
+
puts " >> Probably need to call DigiUSB.refresh() more frequently in Digispark Program".blue
|
33
36
|
rescue Interrupt
|
34
37
|
puts ""
|
35
38
|
end
|
data/lib/digiusb.rb
CHANGED
@@ -1,28 +1,54 @@
|
|
1
|
+
# The DigiUSB class helps find, connect to, and talk with Digisparks using the DigiUSB arduino library bundled with the Digispark Arduino software.
|
2
|
+
# This class aims to work like an IO object, letting you read and write characters, bytes, and strings as if it were a file, socket, or serial port.
|
3
|
+
# To get started, grab a list of Digisparks with the DigiUSB.sparks method. Each spark has an inspect method with a unique identifier including the
|
4
|
+
# USB device name (usually DigiUSB), and some numbers representing which ports and hubs each spark connects to. To begin with, DigiUSB.sparks.last
|
5
|
+
# works well if you only intend to have one digispark connected to your computer. Eventually the device name (aka "product name") will hopefully
|
6
|
+
# provide a simple way to differentiate different digisparks.
|
7
|
+
#
|
8
|
+
# Once you have a reference to a Digispark, you can start using it as if it were an IO object immediately with methods like getc and putc.
|
9
|
+
# As soon as you start interacting with the Digispark using these reading and writing methods the Digispark will be claimed to your ruby program
|
10
|
+
# and will be unavailable to other programs until you do one of: close the ruby program, or unplug and plug back in the Digispark.
|
11
|
+
#
|
12
|
+
# Note also that calling DigiUSB.sparks can sometimes disrupt program uploads, so if you're polling waiting for a digispark to appear you may see
|
13
|
+
# some programming errors in the Digispark Arduino software.
|
14
|
+
|
1
15
|
require 'libusb'
|
2
16
|
|
3
17
|
# simple IO-like read/write access to a digispark using the DigiUSB library
|
4
18
|
class DigiUSB
|
5
|
-
ProductID = 0x05df
|
6
|
-
VendorID = 0x16c0
|
7
|
-
Manufacturer = "digistump.com"
|
19
|
+
ProductID = 0x05df # product id number from Digistump
|
20
|
+
VendorID = 0x16c0 # vendor id number for Digistump
|
21
|
+
Manufacturer = "digistump.com" # manufacturer string is static
|
8
22
|
Timeout = 1_000 # one second till device crashes due to lack of calling DigiUSB.refresh()
|
23
|
+
DefaultPollingFrequency = 15 # 15hz when waiting for data to be printed
|
9
24
|
|
25
|
+
# :nodoc: initialize a new DigiUSB object using a libusb device object
|
10
26
|
def initialize device
|
11
27
|
@device = device
|
12
28
|
@handle = nil
|
29
|
+
@polling_frequency = DefaultPollingFrequency
|
13
30
|
end
|
14
31
|
|
15
|
-
|
32
|
+
# polling frequency describes how aggressively ruby will ask for new bytes when waiting for the device to print something
|
33
|
+
# a lower value is faster (it is in hertz)
|
34
|
+
attr_accessor :polling_frequency
|
35
|
+
|
36
|
+
# Returns an array of all Digisparks connected to this computer. Optionally specify a device name string to return only Digisparks with
|
37
|
+
# that name. At the time of writing there is no easy way to customize the device name in the Digispark Arduino software, but hopefully
|
38
|
+
# there will be in the future.
|
39
|
+
def self.sparks product_name = false
|
16
40
|
usb = LIBUSB::Context.new
|
17
41
|
usb.devices.select { |device|
|
18
|
-
device.idProduct == ProductID && device.idVendor == VendorID && device.manufacturer == "digistump.com"
|
42
|
+
device.idProduct == ProductID && device.idVendor == VendorID && device.manufacturer == "digistump.com" && (product_name == false || product_name.to_s == device.product)
|
19
43
|
}.map { |handle|
|
20
44
|
self.new(handle)
|
21
45
|
}
|
22
46
|
end
|
23
47
|
|
24
48
|
|
25
|
-
# read a single character
|
49
|
+
# Attempt to read a single character from the Digispark. Returns a string either zero or one characters long.
|
50
|
+
# A zero character string means there are no characters available to read - the Digispark hasn't printed anything for you to consume yet.
|
51
|
+
# Returns next time Digispark calls DigiUSB.refresh() regardless of how many characters are available.
|
26
52
|
def getc
|
27
53
|
control_transfer(
|
28
54
|
bRequest: 0x01, # hid get report
|
@@ -30,7 +56,8 @@ class DigiUSB
|
|
30
56
|
)
|
31
57
|
end
|
32
58
|
|
33
|
-
#
|
59
|
+
# Send a single character in to the Digispark's memory. Argument may be either a single byte String, or an integer between 0 and 255 inclusive.
|
60
|
+
# Returns next time Digispark calls DigiUSB.refresh()
|
34
61
|
def putc character
|
35
62
|
character = [character % 256].pack('c') if character.is_a? Integer
|
36
63
|
raise "Cannot putc more than one byte" if character.bytesize > 1
|
@@ -42,20 +69,29 @@ class DigiUSB
|
|
42
69
|
)
|
43
70
|
end
|
44
71
|
|
45
|
-
#
|
72
|
+
# Read a string fromt he Digispark until a newline is received (eg, from the println function in Digispark's DigiUSB library)
|
73
|
+
# The returned string includes a newline character on the end.
|
46
74
|
def gets
|
47
75
|
chars = ""
|
48
|
-
|
76
|
+
until chars.include? "\n"
|
77
|
+
char = getc()
|
78
|
+
chars += char
|
79
|
+
sleep 1.0 / PollingFrequency if char == ""
|
80
|
+
end
|
49
81
|
return chars
|
50
82
|
end
|
83
|
+
alias_method :getln, :gets
|
84
|
+
alias_method :get_line, :gets
|
51
85
|
|
52
|
-
#
|
86
|
+
# Send a String to the Digispark followed by a newline.
|
53
87
|
def puts string = ""
|
54
88
|
write "#{string}\n"
|
55
89
|
end
|
56
90
|
alias_method :println, :puts
|
91
|
+
alias_method :print_line, :puts
|
92
|
+
alias_method :write_line, :puts
|
57
93
|
|
58
|
-
#
|
94
|
+
# Send a String to the Digispark
|
59
95
|
def write string
|
60
96
|
string.each_byte do |byte|
|
61
97
|
putc byte
|
@@ -63,20 +99,45 @@ class DigiUSB
|
|
63
99
|
string
|
64
100
|
end
|
65
101
|
alias_method :print, :write
|
102
|
+
alias_method :send, :write
|
66
103
|
|
67
|
-
#
|
104
|
+
# Recieve a specific number of bytes and return them as a String. Unlike #getc read will wait until
|
105
|
+
# the specified number of bytes are available before returning.
|
68
106
|
def read bytes = 1
|
69
107
|
chars = ""
|
108
|
+
|
109
|
+
until chars.include? "\n"
|
110
|
+
char = getc()
|
111
|
+
chars += char
|
112
|
+
sleep 1.0 / PollingFrequency if char == ""
|
113
|
+
end
|
114
|
+
|
70
115
|
chars += getc() until chars.length == bytes
|
71
116
|
return chars
|
72
117
|
end
|
73
118
|
|
119
|
+
# A friendly textual representation of this specific Digispark. Can be called without claiming the digispark for this program
|
74
120
|
def inspect
|
75
|
-
"<Digispark:#{
|
121
|
+
"<Digispark:#{name}:@#{address}>"
|
76
122
|
end
|
77
123
|
alias_method :to_s, :inspect
|
78
124
|
|
125
|
+
# Return the device name as a String
|
126
|
+
def name
|
127
|
+
@device.product
|
128
|
+
end
|
129
|
+
|
130
|
+
# Returns the device's bus number and address on the computer's USB interface as a string
|
131
|
+
def address
|
132
|
+
"#{@device.bus_number}.#{@device.device_address}"
|
133
|
+
end
|
79
134
|
|
135
|
+
# Release this Digispark so other programs can read and write to it.
|
136
|
+
def close
|
137
|
+
@handle.close
|
138
|
+
@handle = nil
|
139
|
+
end
|
140
|
+
alias_method :release, :close
|
80
141
|
|
81
142
|
private
|
82
143
|
|