beaglebone 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,598 @@
1
+ # == gpio.rb
2
+ # This file contains the GPIO methods
3
+
4
+ module Beaglebone #:nodoc:
5
+ # GPIO
6
+ # procedural methods for GPIO control
7
+ # == Summary
8
+ # #pin_mode is called to initialize a pin.
9
+ # Further basic functionality is available with #digital_read and #digital_write
10
+ module GPIO
11
+ class << self
12
+ # GPIO modes
13
+ MODES = [ :IN, :OUT ]
14
+ # GPIO states
15
+ STATES = { :HIGH => 1, :LOW => 0 }
16
+ # Edge trigger options
17
+ EDGES = [ :NONE, :RISING, :FALLING, :BOTH ]
18
+
19
+ # Initialize a GPIO pin
20
+ #
21
+ # @param pin should be a symbol representing the header pin
22
+ # @param mode should specify the mode of the pin, either :IN or :OUT
23
+ #
24
+ # @example
25
+ # GPIO.pin_mode(:P9_12, :OUT)
26
+ # GPIO.pin_mode(:P9_11, :IN)
27
+ def pin_mode(pin, mode)
28
+
29
+ #make sure a valid mode was passed
30
+ check_valid_mode(mode)
31
+
32
+ #make sure a valid pin was passed and that it supports GPIO
33
+ Beaglebone::check_valid_pin(pin, :gpio)
34
+
35
+ #get info from PINS hash
36
+ pininfo = PINS[pin]
37
+
38
+ #if pin is enabled for something else, disable it
39
+ if Beaglebone::get_pin_status(pin) && Beaglebone::get_pin_status(pin, :type) != :gpio
40
+ Beaglebone::disable_pin(pin)
41
+ end
42
+
43
+ #export pin unless its an on board LED, if it isn't already exported
44
+ if pininfo[:led]
45
+ raise StandardError, "LEDs only support OUT mode: #{pin.to_s}" unless mode == :OUT
46
+ File.open("#{gpio_directory(pin)}/trigger", 'w') { |f| f.write('gpio') }
47
+ else
48
+ File.open('/sys/class/gpio/export', 'w') { |f| f.write pininfo[:gpio] }
49
+ #check to see if pin is GPIO enabled in /sys/class/gpio/
50
+ raise StandardError, "GPIO was unable to initalize pin: #{pin.to_s}" unless enabled?(pin)
51
+ end unless Beaglebone::get_pin_status(pin, :type) == :gpio
52
+
53
+ #set pin mode
54
+ unless pininfo[:led]
55
+ set_gpio_mode(pin, mode)
56
+ dir = read_gpio_direction(pin)
57
+ raise StandardError, "GPIO was unable to set mode: #{pin.to_s} to #{mode.to_s} (#{dir})" if mode != dir
58
+ end
59
+
60
+ Beaglebone::set_pin_status(pin, :mode, mode)
61
+ end
62
+
63
+ # Sets a pin's output state
64
+ #
65
+ # @param pin should be a symbol representing the header pin
66
+ # @param state should be a symbol representin the state, :HIGH or :LOW
67
+ #
68
+ # @example
69
+ # GPIO.digital_write(:P9_12, :HIGH)
70
+ # GPIO.digital_write(:P9_12, :LOW)
71
+ def digital_write(pin, state)
72
+ check_valid_state(state)
73
+ check_gpio_enabled(pin)
74
+
75
+ raise StandardError, "PIN not in GPIO OUT mode: #{pin}" unless get_gpio_mode(pin) == :OUT
76
+
77
+ fd = get_value_fd(pin)
78
+ fd.write STATES[state.to_sym.upcase].to_s
79
+ fd.flush
80
+ Beaglebone::set_pin_status(pin, :state, state)
81
+ end
82
+
83
+ # Reads a pin's input state and return that value
84
+ #
85
+ # @param pin should be a symbol representing the header pin, i.e. :P9_11
86
+ #
87
+ # @return [Symbol] :HIGH or :LOW
88
+ #
89
+ # @example
90
+ # GPIO.digital_read(:P9_11) => :HIGH
91
+ def digital_read(pin)
92
+ check_gpio_enabled(pin)
93
+
94
+ raise StandardError, "PIN not in GPIO IN mode: #{pin}" unless get_gpio_mode(pin) == :IN
95
+
96
+ fd = get_value_fd(pin)
97
+ fd.rewind
98
+ value = fd.read.to_s.strip
99
+ state = STATES.key(value.to_i)
100
+
101
+ Beaglebone::set_pin_status(pin, :state, state)
102
+ end
103
+
104
+ # Runs a callback on an edge trigger event
105
+ # This creates a new thread that runs in the background
106
+ #
107
+ # @param callback A method to call when the edge trigger is detected. This method should take 3 arguments, the pin, the edge, and the counter
108
+ # @param pin should be a symbol representing the header pin, i.e. :P9_11
109
+ # @param edge should be a symbol representing the trigger type, e.g. :RISING, :FALLING, :BOTH
110
+ # @param timeout is optional and specifies a time window to wait
111
+ # @param repeats is optional and specifies the number of times the callback will be run
112
+ #
113
+ # @example
114
+ # GPIO.run_on_edge(lambda { |pin,edge,count| puts "[#{count}] #{pin} -- #{edge}" }, :P9_11, :RISING)
115
+ def run_on_edge(callback, pin, edge, timeout = nil, repeats=nil)
116
+
117
+ raise StandardError, "Already waiting for trigger on pin: #{pin}" if Beaglebone::get_pin_status(pin, :trigger)
118
+ raise StandardError, "Already waiting for trigger on pin: #{pin}" if Beaglebone::get_pin_status(pin, :thread)
119
+
120
+ thread = Thread.new(callback, pin, edge, timeout, repeats) do |c, p, e, t, r|
121
+ begin
122
+ count = 0
123
+ loop do
124
+
125
+ state = wait_for_edge(p, e, t, false)
126
+
127
+ c.call(p, state, count) if c
128
+ count += 1
129
+ break if r && count >= r
130
+ end
131
+ rescue => ex
132
+ puts ex
133
+ puts ex.backtrace
134
+ ensure
135
+ cleanup_edge_trigger(p)
136
+ end
137
+ end
138
+
139
+ Beaglebone::set_pin_status(pin, :thread, thread)
140
+ end
141
+
142
+ # Runs a callback one time on an edge trigger event
143
+ # this is a convenience method for run_on_edge
144
+ # @see #run_on_edge
145
+ def run_once_on_edge(callback, pin, edge, timeout = nil)
146
+ run_on_edge(callback, pin, edge, timeout, 1)
147
+ end
148
+
149
+ # Stops any threads waiting for data on specified pin
150
+ #
151
+ # @param pin should be a symbol representing the header pin, i.e. :P9_11
152
+ def stop_edge_wait(pin)
153
+ thread = Beaglebone::get_pin_status(pin, :thread)
154
+
155
+ thread.exit if thread
156
+ thread.join if thread
157
+ end
158
+
159
+ # Wait for an edge trigger
160
+ # Returns the type that triggered the event, e.g. :RISING, :FALLING, :BOTH
161
+ #
162
+ # @returns [Symbol] :RISING, :FALLING, or :BOTH
163
+ #
164
+ # @param pin should be a symbol representing the header pin, i.e. :P9_11
165
+ # @param edge should be a symbol representing the trigger type, e.g. :RISING, :FALLING, :BOTH
166
+ # @param timeout is optional and specifies a time window to wait
167
+ # @param disable is optional. If set, edge trigger detection is cleared on return
168
+ #
169
+ # @example
170
+ # wait_for_edge(:P9_11, :RISING, 30) => :RISING
171
+ def wait_for_edge(pin, edge, timeout = nil, disable=true)
172
+ check_valid_edge(edge)
173
+ raise ArgumentError, "Cannot wait for edge trigger NONE: #{pin}" if edge.to_sym.upcase == :NONE
174
+
175
+ check_gpio_enabled(pin)
176
+ raise StandardError, "PIN not in GPIO IN mode: #{pin}" unless get_gpio_mode(pin) == :IN
177
+
178
+ #ensure we're the only ones waiting for this trigger
179
+ if Beaglebone::get_pin_status(pin, :thread) && Beaglebone::get_pin_status(pin, :thread) != Thread.current
180
+ raise StandardError, "Already waiting for trigger on pin: #{pin}"
181
+ end
182
+
183
+ if Beaglebone::get_pin_status(pin, :trigger) && Beaglebone::get_pin_status(pin, :thread) != Thread.current
184
+ raise StandardError, "Already waiting for trigger on pin: #{pin}"
185
+ end
186
+
187
+ set_gpio_edge(pin, edge)
188
+
189
+ fd = get_value_fd(pin)
190
+ fd.read
191
+
192
+ #select will return fd into the error set "es" if it recieves an interrupt
193
+ _, _, es = IO.select(nil, nil, [fd], timeout)
194
+
195
+ set_gpio_edge(pin, :NONE) if disable
196
+
197
+ es ? digital_read(pin) : nil
198
+
199
+ end
200
+
201
+ # Resets all the GPIO pins that we have used and unexport them
202
+ def cleanup
203
+ get_gpio_pins.each { |x| disable_gpio_pin(x) }
204
+ end
205
+
206
+ # Returns true if specified pin is enabled in GPIO mode, else false
207
+ def enabled?(pin)
208
+
209
+ return true if Beaglebone::get_pin_status(pin, :type) == :gpio
210
+
211
+ return false unless valid?(pin)
212
+ if Dir.exists?(gpio_directory(pin))
213
+
214
+ Beaglebone::set_pin_status(pin, :type, :gpio)
215
+ return true
216
+ end
217
+
218
+ false
219
+ end
220
+
221
+ # Sends data to a shift register
222
+ #
223
+ # @param latch_pin should be a symbol representing the header pin, i.e. :P9_12
224
+ # @param clock_pin should be a symbol representing the header pin, i.e. :P9_12
225
+ # @param data_pin should be a symbol representing the header pin, i.e. :P9_12
226
+ # @param data Integer value to write to the shift register
227
+ # @param lsb optional, send least significant bit first if set
228
+ #
229
+ # @example
230
+ # GPIO.shift_out(:P9_11, :P9_12, :P9_13, 255)
231
+ def shift_out(latch_pin, clock_pin, data_pin, data, lsb=nil)
232
+ raise ArgumentError, "data must be > 0 (#{date}" if data < 0
233
+ digital_write(latch_pin, :LOW)
234
+
235
+ binary = data.to_s(2)
236
+ pad = 8 - (binary.size % 8 )
237
+ binary = (' ' * pad) + binary
238
+
239
+ binary.reverse! if lsb
240
+
241
+ binary.each_char do |bit|
242
+ digital_write(clock_pin, :LOW)
243
+ digital_write(data_pin, bit == '0' ? :LOW : :HIGH)
244
+ digital_write(clock_pin, :HIGH)
245
+ end
246
+ digital_write(latch_pin, :HIGH)
247
+ end
248
+
249
+ # Returns last known state from +pin+, reads state if unknown
250
+ # @returns [Symbol] :HIGH or :LOW
251
+ def get_gpio_state(pin)
252
+ check_gpio_enabled(pin)
253
+
254
+ state = Beaglebone::get_pin_status(pin, :state)
255
+ return state if state
256
+
257
+ digital_read(pin)
258
+ end
259
+
260
+ # Returns mode from +pin+, reads mode if unknown
261
+ # @returns [Symbol] :IN or :OUT
262
+ def get_gpio_mode(pin)
263
+ check_gpio_enabled(pin)
264
+
265
+ mode = Beaglebone::get_pin_status(pin, :mode)
266
+ return mode if mode
267
+
268
+ read_gpio_direction(pin)
269
+ end
270
+
271
+ # Set GPIO mode on an initialized pin
272
+ #
273
+ # @param pin should be a symbol representing the header pin
274
+ # @param mode should specify the mode of the pin, either :IN or :OUT
275
+ #
276
+ # @example
277
+ # GPIO.set_gpio_mode(:P9_12, :OUT)
278
+ # GPIO.set_gpio_mode(:P9_11, :IN)
279
+ def set_gpio_mode(pin, mode)
280
+ Beaglebone::check_valid_pin(pin, :gpio)
281
+ check_valid_mode(mode)
282
+ check_gpio_enabled(pin)
283
+
284
+ File.open("#{gpio_directory(pin)}/direction", 'w') { |f| f.write mode.to_s.downcase }
285
+ Beaglebone::set_pin_status(pin, :mode, mode)
286
+ end
287
+
288
+ # Set GPIO edge trigger type on an initialized pin
289
+ #
290
+ # @param pin should be a symbol representing the header pin
291
+ # @param edge should be a symbol representing the trigger type, e.g. :RISING, :FALLING, :BOTH
292
+ # @param force is optional, if set will set the mode even if already set
293
+ #
294
+ # @example
295
+ # GPIO.set_gpio_edge(:P9_11, :RISING)
296
+ def set_gpio_edge(pin, edge, force=nil)
297
+ check_valid_edge(edge)
298
+ Beaglebone::check_valid_pin(pin, :gpio)
299
+
300
+ raise StandardError, "PIN not in GPIO IN mode: #{pin}" unless get_gpio_mode(pin) == :IN
301
+
302
+ return if get_gpio_edge(pin) == edge && !force
303
+
304
+ File.open("#{gpio_directory(pin)}/edge", 'w') { |f| f.write edge.to_s.downcase }
305
+ testedge = read_gpio_edge(pin)
306
+ if testedge != edge.to_s.downcase
307
+ Beaglebone::delete_pin_status(pin, :trigger)
308
+ raise StandardError, "GPIO was unable to set edge: #{pin.to_s} to #{edge.to_s}"
309
+ end
310
+
311
+ if edge.to_sym == :NONE
312
+ Beaglebone::delete_pin_status(pin, :trigger)
313
+ else
314
+ Beaglebone::set_pin_status(pin, :trigger, edge.to_sym)
315
+ end
316
+
317
+ end
318
+
319
+ # Returns the GPIO edge trigger type on an initialized pin
320
+ # @return [Symbol] :NONE, :RISING, :FALLING, or :BOTH
321
+ def get_gpio_edge(pin)
322
+ check_gpio_enabled(pin)
323
+
324
+ edge = Beaglebone::get_pin_status(pin, :trigger)
325
+ return edge if edge
326
+
327
+ read_gpio_edge(pin)
328
+ end
329
+
330
+ # Return an array of GPIO pins in use
331
+ #
332
+ # @return [Array<Symbol>]
333
+ #
334
+ # @example
335
+ # GPIO.get_gpio_pins => [:P9_12, :P9_13]
336
+ def get_gpio_pins
337
+ Beaglebone.pinstatus.clone.select { |x,y| x if y[:type] == :gpio && !PINS[x][:led] }.keys
338
+ end
339
+
340
+ # Disable a GPIO pin
341
+ #
342
+ # @param pin should be a symbol representing the header pin
343
+ def disable_gpio_pin(pin)
344
+
345
+ Beaglebone::check_valid_pin(pin, :gpio)
346
+
347
+ pininfo = PINS[pin]
348
+
349
+ close_value_fd(pin)
350
+
351
+ #close any running threads
352
+ stop_edge_wait(pin)
353
+
354
+ #write to unexport to disable gpio
355
+ File.open('/sys/class/gpio/unexport', 'w') { |f| f.write(pininfo[:gpio]) }
356
+
357
+ #remove status from hash so following enabled? call checks actual system
358
+ Beaglebone::delete_pin_status(pin)
359
+
360
+ #check to see if pin is GPIO enabled in /sys/class/gpio/
361
+ raise StandardError, "GPIO was unable to uninitalize pin: #{pin.to_s}" if enabled?(pin)
362
+
363
+ end
364
+
365
+ private
366
+
367
+ #ensure edge type is valid
368
+ def check_valid_edge(edge)
369
+ raise ArgumentError, "No such edge: #{edge.to_s}" unless EDGES.include?(edge)
370
+ end
371
+
372
+ #read gpio edge file
373
+ def read_gpio_edge(pin)
374
+ check_gpio_enabled(pin)
375
+ File.open("#{gpio_directory(pin)}/edge", 'r').read.to_s.strip
376
+ end
377
+
378
+ #check if pin is valid to use as gpio pin
379
+ def valid?(pin)
380
+ #check to see if pin exists
381
+ pin = pin.to_sym.upcase
382
+
383
+ return false unless PINS[pin]
384
+ return false unless PINS[pin][:gpio]
385
+
386
+ true
387
+ end
388
+
389
+ #set edge trigger to none
390
+ def cleanup_edge_trigger(pin)
391
+ if Beaglebone::get_pin_status(pin, :thread) == Thread.current
392
+ set_gpio_edge(pin, :NONE)
393
+ Beaglebone::delete_pin_status(pin, :thread)
394
+ end
395
+ end
396
+
397
+ #convenience method for getting gpio dir in /sys
398
+ def gpio_directory(pin)
399
+ raise StandardError, 'Invalid Pin' unless valid?(pin)
400
+ #led's are in a special place
401
+ if PINS[pin][:led]
402
+ "/sys/class/leds/beaglebone:green:#{pin.to_s.downcase}"
403
+ else
404
+ #normal gpio pins
405
+ "/sys/class/gpio/gpio#{PINS[pin][:gpio]}"
406
+ end
407
+ end
408
+
409
+ #read gpio direction file
410
+ def read_gpio_direction(pin)
411
+ check_gpio_enabled(pin)
412
+
413
+ Beaglebone::set_pin_status(pin, :mode, File.open("#{gpio_directory(pin)}/direction", 'r').read.to_s.strip.to_sym.upcase)
414
+ end
415
+
416
+ #return the open value fd, or open if needed
417
+ def get_value_fd(pin)
418
+ check_gpio_enabled(pin)
419
+
420
+ fd = Beaglebone::get_pin_status(pin, :fd_value)
421
+ return fd if fd
422
+
423
+ pininfo = PINS[pin]
424
+
425
+ #leds aren't normal gpio pins, we can toggle them on and off however.
426
+ if pininfo[:led]
427
+ fd = File.open("#{gpio_directory(pin)}/brightness", 'w+')
428
+ else
429
+ fd = File.open("#{gpio_directory(pin)}/value", 'w+')
430
+ end
431
+
432
+ Beaglebone::set_pin_status(pin, :fd_value, fd)
433
+ end
434
+
435
+ #close value fd if open
436
+ def close_value_fd(pin)
437
+ fd = Beaglebone::get_pin_status(pin, :fd_value)
438
+ fd.close if fd
439
+ Beaglebone::delete_pin_status(pin, :fd_value)
440
+ end
441
+
442
+ #ensure state is valid
443
+ def check_valid_state(state)
444
+ #check to see if mode is valid
445
+ state = state.to_sym.upcase
446
+ raise ArgumentError, "No such state: #{state.to_s}" unless STATES.include?(state)
447
+ end
448
+
449
+ #ensure mode is valid
450
+ def check_valid_mode(mode)
451
+ #check to see if mode is valid
452
+ mode = mode.to_sym.upcase
453
+ raise ArgumentError, "No such mode: #{mode.to_s}" unless MODES.include?(mode)
454
+ end
455
+
456
+ #ensure gpio pin is enabled
457
+ def check_gpio_enabled(pin)
458
+ Beaglebone::check_valid_pin(pin, :gpio)
459
+ raise StandardError, "PIN not GPIO enabled: #{pin}" unless enabled?(pin)
460
+ end
461
+
462
+ end
463
+ end
464
+
465
+ # Object Oriented GPIO Implementation.
466
+ # This treats the pin as an object.
467
+ class GPIOPin
468
+
469
+ # Initialize a GPIO pin
470
+ # Return's a GPIOPin object, setting the pin mode on initialization
471
+ #
472
+ # @param mode should specify the mode of the pin, either :IN or :OUT
473
+ #
474
+ # @return [GPIOPin]
475
+ #
476
+ # @example
477
+ # p9_12 = GPIOPin.new(:P9_12, :OUT)
478
+ # p9_11 = GPIOPin.new(:P9_11, :IN)
479
+ def initialize(pin, mode)
480
+ @pin = pin
481
+
482
+ GPIO::pin_mode(@pin, mode)
483
+ end
484
+
485
+ # Sets a pin's output state
486
+ #
487
+ # @param state should be a symbol representin the state, :HIGH or :LOW
488
+ #
489
+ # @example
490
+ # p9_12 = GPIOPin.new(:P9_12, :OUT)
491
+ # p9_12.digital_write(:HIGH)
492
+ # p9_12.digital_write(:LOW)
493
+ def digital_write(state)
494
+ GPIO::digital_write(@pin, state)
495
+ end
496
+
497
+ # Reads a pin's input state and return that value
498
+ #
499
+ # @return [Symbol] :HIGH or :LOW
500
+ #
501
+ # @example
502
+ # p9_11 = GPIOPin.new(:P9_12, :OUT)
503
+ # p9_11.digital_read => :HIGH
504
+ def digital_read
505
+ GPIO::digital_read(@pin)
506
+ end
507
+
508
+ # Runs a callback on an edge trigger event
509
+ # This creates a new thread that runs in the background
510
+ #
511
+ # @param callback A method to call when the edge trigger is detected. This method should take 3 arguments, the pin, the edge, and the counter
512
+ # @param edge should be a symbol representing the trigger type, e.g. :RISING, :FALLING, :BOTH
513
+ # @param timeout is optional and specifies a time window to wait
514
+ # @param repeats is optional and specifies the number of times the callback will be run
515
+ #
516
+ # @example
517
+ # p9_11 = GPIOPin.new(:P9_11, :IN)
518
+ # p9_11.run_on_edge(lambda { |pin,edge,count| puts "[#{count}] #{pin} -- #{edge}" }, :P9_11, :RISING) def run_on_edge(callback, edge, timeout=nil, repeats=nil)
519
+ def run_on_edge(callback, edge, timeout=nil, repeats=nil)
520
+ GPIO::run_on_edge(callback, @pin, edge, timeout, repeats)
521
+ end
522
+
523
+ # Runs a callback one time on an edge trigger event
524
+ # this is a convenience method for run_on_edge
525
+ # @see #run_on_edge
526
+ def run_once_on_edge(callback, edge, timeout=nil)
527
+ GPIO::run_once_on_edge(callback, @pin, edge, timeout)
528
+ end
529
+
530
+ # Stops any threads waiting for data on this pin
531
+ #
532
+ def stop_edge_wait
533
+ GPIO::stop_edge_wait(@pin)
534
+ end
535
+
536
+ # Wait for an edge trigger
537
+ # Returns the type that triggered the event, e.g. :RISING, :FALLING, :BOTH
538
+ #
539
+ # @return [Symbol] :RISING, :FALLING, or :BOTH
540
+ #
541
+ # @param edge should be a symbol representing the trigger type, e.g. :RISING, :FALLING, :BOTH
542
+ # @param timeout is optional and specifies a time window to wait
543
+ #
544
+ # @example
545
+ # p9_11 = GPIOPin.new(:P9_11, :IN)
546
+ # p9_11.wait_for_edge(:RISING, 30) => :RISING
547
+ def wait_for_edge(edge, timeout=nil)
548
+ GPIO::wait_for_edge(@pin, edge, timeout)
549
+ end
550
+
551
+ # Returns last known state from +pin+, reads state if unknown
552
+ # @return [Symbol] :HIGH or :LOW
553
+ def get_gpio_state
554
+ GPIO::get_gpio_state(@pin)
555
+ end
556
+
557
+ # Returns mode from pin, reads mode if unknown
558
+ # @return [Symbol] :IN or :OUT
559
+ def get_gpio_mode
560
+ GPIO::get_gpio_mode(@pin)
561
+ end
562
+
563
+ # Returns the GPIO edge trigger type
564
+ # @return [Symbol] :NONE, :RISING, :FALLING, or :BOTH
565
+ def get_gpio_edge
566
+ GPIO::get_gpio_edge(@pin)
567
+ end
568
+
569
+
570
+ # Set GPIO mode on an initialized pin
571
+ #
572
+ # @param mode should specify the mode of the pin, either :IN or :OUT
573
+ #
574
+ # @example
575
+ # p9_12.set_gpio_mode(:OUT)
576
+ # p9_11.set_gpio_mode(:IN)
577
+ def set_gpio_mode(mode)
578
+ GPIO::set_gpio_mode(@pin, mode)
579
+ end
580
+
581
+ # Set GPIO edge trigger type
582
+ #
583
+ # @param edge should be a symbol representing the trigger type, e.g. :RISING, :FALLING, :BOTH
584
+ # @param force is optional, if set will set the mode even if already set
585
+ #
586
+ # @example
587
+ # p9_11.set_gpio_edge(:RISING)
588
+ def set_gpio_edge(edge, force=nil)
589
+ GPIO::set_gpio_edge(@pin, edge, force)
590
+ end
591
+
592
+ # Disable GPIO pin
593
+ def disable_gpio_pin
594
+ GPIO::disable_gpio_pin(@pin)
595
+ end
596
+
597
+ end
598
+ end