beaglebone 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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