beaglebone 1.0.6 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +97 -14
- data/beaglebone.gemspec +1 -1
- data/procedural-examples.md +614 -0
- metadata +2 -8
- data/examples/ain.rb +0 -92
- data/examples/gpio.rb +0 -196
- data/examples/i2c.rb +0 -110
- data/examples/pwm.rb +0 -63
- data/examples/shiftregister.rb +0 -12
- data/examples/spi.rb +0 -62
- data/examples/uart.rb +0 -64
@@ -0,0 +1,614 @@
|
|
1
|
+
TODO: convert this to procedural methods.
|
2
|
+
|
3
|
+
**Table of Contents**
|
4
|
+
- [Examples (Procedural)](#examples-procedural)
|
5
|
+
- [GPIO](#gpio)
|
6
|
+
- [GPIO Writing](#gpio-writing)
|
7
|
+
- [GPIO Reading](#gpio-reading)
|
8
|
+
- [LEDs](#leds)
|
9
|
+
- [Edge Triggers](#edge-triggers)
|
10
|
+
- [Edge Triggers in the Background](#edge-triggers-in-the-background)
|
11
|
+
- [Shift Registers](#shift-registers)
|
12
|
+
- [Analog Inputs](#analog-inputs)
|
13
|
+
- [Reading](#reading)
|
14
|
+
- [Waiting for Change](#waiting-for-change)
|
15
|
+
- [Waiting for Change in the Background](#waiting-for-change-in-the-background)
|
16
|
+
- [Waiting for Threshold](#waiting-for-threshold)
|
17
|
+
- [Waiting for Threshold in the Background](#waiting-for-Threshold-in-the-background)
|
18
|
+
- [PWM](#pwm)
|
19
|
+
- [UART](#uart)
|
20
|
+
- [UART Writing](#uart-writing)
|
21
|
+
- [UART Reading](#uart-reading)
|
22
|
+
- [UART Reading and Iterating](#uart-reading-and-iterating)
|
23
|
+
- [UART Reading and Iterating in the Background](#uart-reading-and-iterating-in-the-background)
|
24
|
+
- [I2C](#i2c)
|
25
|
+
- [I2C Writing](#i2c-writing)
|
26
|
+
- [I2C Reading](#i2c-reading)
|
27
|
+
- [LSM303DLHC Example](#lsm303dlhc-example)
|
28
|
+
- [SPI](#spi)
|
29
|
+
- [SPI Data Transfer](#spi-data-transfer)
|
30
|
+
- [MCP3008 Example](#mcp3008-example)
|
31
|
+
|
32
|
+
## Examples (Procedural)
|
33
|
+
These examples will show the various ways to interact with the Beaglebones IO hardware. They will need to be executed as root in order to function correctly.
|
34
|
+
|
35
|
+
### GPIO
|
36
|
+
The GPIO pins on the Beaglebone run at **3.3v**. Do not provide more than 3.3v to any GPIO pin or risk damaging the hardware.
|
37
|
+
|
38
|
+
GPIO pins have two modes, input and output. These modes are represented by the symbols **:IN** and **:OUT**.
|
39
|
+
|
40
|
+
To initialize the pin **P9_11**, pass the symbol for that pin and the mode to the **GPIO.pin_mode** method.
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
# Initialize pin P9_11 in INPUT mode
|
44
|
+
GPIO.pin_mode(:P9_11, :IN)
|
45
|
+
|
46
|
+
# Initialize pin P9_12 in OUTPUT mode
|
47
|
+
GPIO.pin_mode(:P9_12, :OUT)
|
48
|
+
|
49
|
+
# Change pin P9_12 to INPUT mode
|
50
|
+
GPIO.set_gpio_mode(:P9_12, :IN)
|
51
|
+
|
52
|
+
# Disable pin P9_12
|
53
|
+
GPIO.disable_gpio_pin(:P9_12)
|
54
|
+
```
|
55
|
+
|
56
|
+
#### GPIO Writing
|
57
|
+
To set the state of a GPIO pin, the method **GPIO.digital_write** is used. The states that can be set are **:HIGH** to provide 3.3v and **:LOW** to provide ground.
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
# Initialize pin P9_12 in OUTPUT mode
|
61
|
+
GPIO.pin_mode(:P9_12, :OUT)
|
62
|
+
|
63
|
+
# Provide 3.3v on pin P9_12
|
64
|
+
GPIO.digital_write(:P9_12, :HIGH)
|
65
|
+
|
66
|
+
# Provide ground on pin P9_12
|
67
|
+
GPIO.digital_write(:P9_12, :LOW)
|
68
|
+
```
|
69
|
+
|
70
|
+
#### GPIO Reading
|
71
|
+
To read the current state of a GPIO pin, the method **GPIO.digital_read** is used. It will return the symbol **:HIGH** or **:LOW** depending on the state of the pin.
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
# Initialize pin P9_11 in INPUT mode
|
75
|
+
GPIO.pin_mode(:P9_11, :IN)
|
76
|
+
|
77
|
+
# Get the current state of P9_11
|
78
|
+
state = GPIO.digital_read(:P9_11) => :LOW
|
79
|
+
```
|
80
|
+
|
81
|
+
#### LEDs
|
82
|
+
The on-board LEDs are addressable via GPIO output. They are available on pins **:USR0** through **:USR3**.
|
83
|
+
|
84
|
+
This example will blink each LED in order 5 times.
|
85
|
+
|
86
|
+
```ruby
|
87
|
+
# Initialize each LED pin
|
88
|
+
leds = [ :USR0, :USR1, :USR2, :USR3 ]
|
89
|
+
leds.each do |ledpin|
|
90
|
+
GPIO.pin_mode(ledpin, :OUT)
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
# Run the following block 5 times
|
95
|
+
5.times do
|
96
|
+
# Iterate over each LED
|
97
|
+
leds.each do |ledpin|
|
98
|
+
# Turn on the LED
|
99
|
+
GPIO.digital_write(ledpin, :HIGH)
|
100
|
+
# Delay 0.25 seconds
|
101
|
+
sleep 0.25
|
102
|
+
# Turn off the LED
|
103
|
+
GPIO.digital_write(ledpin, :LOW)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
```
|
107
|
+
|
108
|
+
#### Edge Triggers
|
109
|
+
The Beaglebone can also monitor for changes on a GPIO pin. This is called an edge trigger. Since this is interrupt based on the Beaglebone, waiting for a change does not waste CPU cycles by constantly polling the pin.
|
110
|
+
|
111
|
+
The following trigger types are supported
|
112
|
+
- Rising: Triggered when the state goes from low to high
|
113
|
+
- Falling: Triggered when the state goes from high to low
|
114
|
+
- Both: Triggered at any change in state
|
115
|
+
- None: Triggering is disabled
|
116
|
+
|
117
|
+
These trigger types are represented by the symbols :RISING, :FALLING, :BOTH, and :NONE
|
118
|
+
|
119
|
+
This example will wait for a rising edge to continue, then output the type of edge trigger that was detected.
|
120
|
+
|
121
|
+
```ruby
|
122
|
+
# Initialize pin P9_11 in INPUT mode
|
123
|
+
GPIO.pin_mode(:P9_11, :IN)
|
124
|
+
|
125
|
+
# Wait here until a rising edge is detected
|
126
|
+
edge = GPIO.wait_for_edge(:P9_11, :RISING) => :RISING
|
127
|
+
|
128
|
+
# Output the trigger type detected
|
129
|
+
puts "Saw a #{edge} edge"
|
130
|
+
```
|
131
|
+
|
132
|
+
#### Edge Triggers in the Background
|
133
|
+
To avoid blocking while waiting for an edge trigger, the method **GPIO.run_on_edge** will run a callback when an edge trigger is detected. This method will spawn a new thread and wait for an edge trigger in the background. Only one of these threads may be active per pin.
|
134
|
+
|
135
|
+
This example will detect edge triggers in the background and output information when triggered.
|
136
|
+
|
137
|
+
```ruby
|
138
|
+
# Initialize pin P9_11 in INPUT mode
|
139
|
+
GPIO.pin_mode(:P9_11, :IN)
|
140
|
+
|
141
|
+
# Define callback to run when an edge trigger is detected
|
142
|
+
# This method takes 3 arguments.
|
143
|
+
# pin: The pin that triggered the event
|
144
|
+
# edge: The event that triggered it
|
145
|
+
# count: How many times it has been triggered
|
146
|
+
callback = lambda { |pin,edge,count| puts "[#{count}] #{pin} #{edge}"}
|
147
|
+
|
148
|
+
# Run the callback every time a change in state is detected
|
149
|
+
# This method has two additional arguments that are optional.
|
150
|
+
# Timeout: How long to wait for an event before terminating the thread
|
151
|
+
# Repeats: How many times to run the event
|
152
|
+
# By default, it will run forever every time the specified trigger is detected
|
153
|
+
GPIO.run_on_edge(callback, :P9_11, :BOTH)
|
154
|
+
|
155
|
+
# This code will run immediately after the previous call, as it does not block
|
156
|
+
sleep 10
|
157
|
+
|
158
|
+
# Stop the background thread waiting for an edge trigger after 10 seconds
|
159
|
+
GPIO.stop_edge_wait(:P9_11)
|
160
|
+
|
161
|
+
# This convenience method will run the callback only on the first detected change
|
162
|
+
GPIO.run_once_on_edge(callback, :P9_11, :BOTH)
|
163
|
+
|
164
|
+
# Change the trigger detection for the specified pin
|
165
|
+
GPIO.set_gpio_edge(:P9_11, :RISING)
|
166
|
+
```
|
167
|
+
|
168
|
+
#### Shift Registers
|
169
|
+
This library will also support writing to shift registers using GPIO pins. Create a **ShiftRegister** object by initializing it with the latch pin, clock pin, and data pin.
|
170
|
+
|
171
|
+
This example will trigger 8 pins of a shift register.
|
172
|
+
|
173
|
+
```ruby
|
174
|
+
# P9_11 is connected to the latch pin
|
175
|
+
# P9_12 is connected to the clock pin
|
176
|
+
# P9_13 is connected to the data pin
|
177
|
+
|
178
|
+
# Initialize the pins connected to shift register
|
179
|
+
GPIO.pin_mode(:P9_11, :OUT)
|
180
|
+
GPIO.pin_mode(:P9_12, :OUT)
|
181
|
+
GPIO.pin_mode(:P9_13, :OUT)
|
182
|
+
|
183
|
+
# Write value to shift register
|
184
|
+
GPIO.shift_out(:P9_11, :P9_12, :P9_13, 0b11111111)
|
185
|
+
```
|
186
|
+
|
187
|
+
### Analog Inputs
|
188
|
+
The Analog pins on the Beaglebone run at **1.8v**. Do not provide more than 1.8v to any analog pin or risk damaging the hardware. The header has pins available to provide a 1.8v for analog devices as well as a dedicated analog ground. Analog pins are only capable of reading input values.
|
189
|
+
|
190
|
+
Analog pins do not require setup, and can be read at any time
|
191
|
+
|
192
|
+
#### Reading
|
193
|
+
To read the value from an analog pin, the method **AIN.read** is used. This will return a value between 0 and 1799.
|
194
|
+
|
195
|
+
```ruby
|
196
|
+
# Read the input value in millivolts.
|
197
|
+
mv = AIN.read(:P9_33) => 1799
|
198
|
+
```
|
199
|
+
|
200
|
+
#### Waiting for Change
|
201
|
+
To wait for the value of an analog pin to change by a specified voltage, the method **AIN.wait_for_change** is used.
|
202
|
+
|
203
|
+
**AIN.wait_for_change** takes the following arguments.
|
204
|
+
- pin: The symbol of the pin to monitor
|
205
|
+
- mv_change: The amount of change in millivolts required before returning
|
206
|
+
- interval: How often to poll the value of the pin in seconds
|
207
|
+
- mv_last: (optional) The initial value to use as a point to detect change
|
208
|
+
|
209
|
+
This method returns an array containing the initial voltage, the last polled voltage, and the number of times the pin was polled.
|
210
|
+
|
211
|
+
```ruby
|
212
|
+
# Wait for 100mv of change on pin P9_33. Poll 10 times a second
|
213
|
+
mv_start, mv_current, count = AIN.wait_for_change(:P9_33, 100, 0.1)
|
214
|
+
```
|
215
|
+
|
216
|
+
#### Waiting for Change in the Background
|
217
|
+
To avoid blocking while waiting for voltage change, the method **AIN.run_on_change** will run a callback every time the specified change is detected. This method will spawn a new thread and wait for change in the background. The method **AIN.run_once_on_change** is a convenience method to only be triggered once. Only one of these threads may be active per pin.
|
218
|
+
|
219
|
+
This example waits for voltage change in the background and outputs information when change is detected.
|
220
|
+
|
221
|
+
```ruby
|
222
|
+
|
223
|
+
# Define callback to run when condition is met
|
224
|
+
# This method takes 4 arguments.
|
225
|
+
# pin: The pin that triggered the event
|
226
|
+
# mv_last: The initial voltage used to determine change
|
227
|
+
# mv: The current voltage on the pin
|
228
|
+
# count: How many times it has been triggered
|
229
|
+
callback = lambda { |pin, mv_last, mv, count| puts "[#{count}] #{pin} #{mv_last} -> #{mv}" }
|
230
|
+
|
231
|
+
# Run the callback every time the specified voltage change is detected
|
232
|
+
# This method has one additional argument that is optional.
|
233
|
+
# Repeats: How many times to will run the event
|
234
|
+
# By default, it will run forever every time the specified condition is detected
|
235
|
+
# Detect 10mv of change polling 10 times a second.
|
236
|
+
AIN.run_on_change(callback, :P9_33, 10, 0.1)
|
237
|
+
|
238
|
+
# This code will run immediately after the previous call, as it does not block
|
239
|
+
sleep 20
|
240
|
+
|
241
|
+
# Stop the background thread after 20 seconds
|
242
|
+
AIN.stop_wait(:P9_33)
|
243
|
+
```
|
244
|
+
|
245
|
+
#### Waiting for Threshold
|
246
|
+
To wait for the value of an analog pin to cross certain threshold voltages, the method **AIN.wait_for_threshold** is used.
|
247
|
+
|
248
|
+
**AIN.wait_for_threshold** takes the following arguments.
|
249
|
+
- pin: The symbol of the pin to monitor
|
250
|
+
- mv_lower: The lower threshold value in millivolts
|
251
|
+
- mv_upper: The upper threshold value in millivolts
|
252
|
+
- mv_reset: The voltage change required to cross out of the lower or upper threshold ranges.
|
253
|
+
- interval: How often to poll the value of the pin in seconds
|
254
|
+
- mv_last: (optional) The initial value to use as a point to detect change
|
255
|
+
- state_last: (optional) The initial state to use as a point to detect change
|
256
|
+
|
257
|
+
Three states are available.
|
258
|
+
- :LOW: below or equal to mv_lower
|
259
|
+
- :MID: above mv_lower and below mv_upper
|
260
|
+
- :HIGH: above or equal to mv_upper
|
261
|
+
|
262
|
+
This method returns an array containing the initial voltage, the last polled voltage, the initial state, the last polled state, and the number of times the pin was polled.
|
263
|
+
|
264
|
+
```ruby
|
265
|
+
# Wait for the voltage on pin P9_33 to go below 200mv or above 1600mv.
|
266
|
+
# To enter the :MID state from :HIGH or :LOW, it will have to cross the thresholds by at least 100mv.
|
267
|
+
# Poll 10 times a second
|
268
|
+
data = AIN.wait_for_threshold(:P9_33, 200, 1600, 100, 0.1) => [ 500, 150, :MID, :LOW, 53 ]
|
269
|
+
|
270
|
+
# Assign variables from array
|
271
|
+
mv_start, mv_current, state_start, state_current, count = data
|
272
|
+
```
|
273
|
+
|
274
|
+
#### Waiting for Threshold in the Background
|
275
|
+
To avoid blocking while waiting for a voltage threshold to be crossed, the method **AIN.run_on_threshold** will run a callback every time the specified change is detected. This method will spawn a new thread and wait for change in the background. The method **AIN.run_once_on_threshold** is a convenience method to only be triggered once. Only one of these threads may be active per pin.
|
276
|
+
|
277
|
+
This example waits for voltage change in the background and outputs information when the specified threshold is crossed.
|
278
|
+
|
279
|
+
```ruby
|
280
|
+
# Define callback to run when condition is met
|
281
|
+
# This method takes 6 arguments.
|
282
|
+
# pin: The pin that triggered the event
|
283
|
+
# mv_last: The initial voltage used to determine change
|
284
|
+
# mv: The current voltage on the pin
|
285
|
+
# state_last: The initial state to use as a point to detect change
|
286
|
+
# state: The current state of the pin
|
287
|
+
# count: How many times it has been triggered
|
288
|
+
callback = lambda { |pin, mv_last, mv, state_last, state, count|
|
289
|
+
puts "[#{count}] #{pin} #{state_last} -> #{state} #{mv_last} -> #{mv}"
|
290
|
+
}
|
291
|
+
|
292
|
+
# Run the callback every time the specified voltage threshold is crossed
|
293
|
+
# This method has one additional argument that is optional.
|
294
|
+
# Repeats: How many times to will run the event
|
295
|
+
# By default, it will run forever every time the specified condition is detected
|
296
|
+
# Wait for the voltage on pin P9_33 to go below 200mv or above 1600mv.
|
297
|
+
# To enter the :MID state from :HIGH or :LOW, it will have to cross the thresholds by at least 100mv.
|
298
|
+
# Poll 10 times a second
|
299
|
+
# Run callback when state changes
|
300
|
+
AIN.run_on_threshold(callback, :P9_33, 200, 1600, 100, 0.1)
|
301
|
+
|
302
|
+
# This code will run immediately after the previous call, as it does not block
|
303
|
+
sleep 20
|
304
|
+
|
305
|
+
# Stop the background thread after 20 seconds
|
306
|
+
AIN.stop_wait(:P9_33)
|
307
|
+
```
|
308
|
+
|
309
|
+
### PWM
|
310
|
+
The beaglebone supports PWM (pulse width modulated) output on certain pins. These pins output 3.3v. The output is controlled based on frequency and duty cycle.
|
311
|
+
|
312
|
+
To initialize the pin **P9_14**, pass the symbol for that pin, the duty cycle, and the frequency in Hz to the **PWM.start** method.
|
313
|
+
|
314
|
+
This example shows how to control PWM output of a specified pin.
|
315
|
+
|
316
|
+
```ruby
|
317
|
+
# Initialize pin P9_14 for PWM output
|
318
|
+
# This pin will now output a square wave at 10Hz with a 90% duty cycle.
|
319
|
+
PWM.start(:P9_14, 90, 10)
|
320
|
+
|
321
|
+
# Change frequency to 20Hz. Duty cycle remains 90%
|
322
|
+
PWM.set_frequency(:P9_14, 20)
|
323
|
+
|
324
|
+
# Change the duty cycle to 50%
|
325
|
+
PWM.set_duty_cycle(:P9_14, 50)
|
326
|
+
|
327
|
+
# Adjust the frequency by setting the period in nanoseconds.
|
328
|
+
PWM.set_period_ns(:P9_14, 31250000)
|
329
|
+
|
330
|
+
# Adjust the duty cycle by setting the period in nanoseconds.
|
331
|
+
PWM.set_duty_cycle_ns(:P9_14, 31250000)
|
332
|
+
|
333
|
+
# Invert the output signal
|
334
|
+
PWM.set_polarity(:P9_14, :INVERTED)
|
335
|
+
|
336
|
+
# Stop the output signal
|
337
|
+
PWM.stop(:P9_14)
|
338
|
+
|
339
|
+
# Resume the output signal
|
340
|
+
PWM.run(:P9_14)
|
341
|
+
|
342
|
+
# Disable the output signal
|
343
|
+
PWM.disable_pwm_pin(:P9_14)
|
344
|
+
```
|
345
|
+
|
346
|
+
### UART
|
347
|
+
The beaglebone has a number of UART devices. These operate in TTL mode at 3.3v. Do not provide more than 3.3v to the pins or risk damaging the hardware.
|
348
|
+
|
349
|
+
Please note, UART3 does not have an RX pin, and UART5 is only available if the HDMI device tree is not enabled.
|
350
|
+
|
351
|
+
To initialize the UART device **UART1**, pass the symbol for that device and the speed to the **UART.setup** method.
|
352
|
+
|
353
|
+
```ruby
|
354
|
+
# Initialize the pins for device UART1 into UART mode.
|
355
|
+
UART.setup(:UART1, 9600)
|
356
|
+
|
357
|
+
# Change the speed of a UART device by calling #set_speed
|
358
|
+
UART.set_speed(:UART1, 115200)
|
359
|
+
|
360
|
+
# Disable UART device
|
361
|
+
UART.disable(:UART1)
|
362
|
+
```
|
363
|
+
|
364
|
+
#### UART Writing
|
365
|
+
Writing to a UART device is accomplished by calling the **UART.write** or **UART.writeln** methods
|
366
|
+
```ruby
|
367
|
+
# Initialize the pins for device UART1 into UART mode.
|
368
|
+
UART.setup(:UART1, 9600)
|
369
|
+
|
370
|
+
# Write data to a UART1
|
371
|
+
UART.write(:UART1, "DATA DATA DATA!")
|
372
|
+
|
373
|
+
# Write data to UART1 followed by a line feed
|
374
|
+
UART.writeln(:UART1, "A line feed follows")
|
375
|
+
```
|
376
|
+
|
377
|
+
#### UART Reading
|
378
|
+
There are many methods available for reading from UART devices. These are blocking methods and will not return until the requested is available.
|
379
|
+
|
380
|
+
```ruby
|
381
|
+
# Initialize the pins for device UART1 into UART mode.
|
382
|
+
UART.setup(:UART1, 9600)
|
383
|
+
|
384
|
+
# Read one character from UART1
|
385
|
+
c = UART.readchar(:UART1) => "X"
|
386
|
+
|
387
|
+
# Read 10 characters from UART1
|
388
|
+
str = UART.readchars(:UART1, 10) => "0123456789"
|
389
|
+
|
390
|
+
# Read a line from UART1
|
391
|
+
line = UART.readline(:UART1) => "All the text up until the linefeed"
|
392
|
+
```
|
393
|
+
|
394
|
+
#### UART Reading and Iterating
|
395
|
+
Data read from the UART device may be iterated with the following methods. These are blocking methods and will run until the loop is broken.
|
396
|
+
|
397
|
+
```ruby
|
398
|
+
# Initialize the pins for device UART1 into UART mode.
|
399
|
+
UART.setup(:UART1, 9600)
|
400
|
+
|
401
|
+
# Run block on every character read from UART1
|
402
|
+
UART.each_char(:UART1) { |c| puts c }
|
403
|
+
|
404
|
+
# Run block on every 5 character read from UART1
|
405
|
+
UART.each_char(:UART1, 5) { |str| puts str }
|
406
|
+
|
407
|
+
# Run block on each line read from UART1
|
408
|
+
UART.each_line(:UART1) { |line| puts line }
|
409
|
+
```
|
410
|
+
|
411
|
+
#### UART Reading and Iterating in the Background
|
412
|
+
Data read from the UART device may be iterated in the background with the following methods. The data read is passed to the specified callback. These method will spawn a new thread and wait for data in the background. Only one of these threads may be active per pin.
|
413
|
+
|
414
|
+
This example shows various methods of reading and processing data read from UART1 in the background.
|
415
|
+
|
416
|
+
```ruby
|
417
|
+
# Initialize the pins for device UART1 into UART mode.
|
418
|
+
UART.setup(:UART1, 9600)
|
419
|
+
|
420
|
+
# Define the callback to be run. It takes 3 arguments
|
421
|
+
# uart: the UART device that triggered the callback
|
422
|
+
# data: the data read from the UART
|
423
|
+
# count: how many times this was triggered
|
424
|
+
callback = lambda { |uart, data, count| puts "[#{uart}:#{count}] #{data}" }
|
425
|
+
|
426
|
+
# Run callback for every character read
|
427
|
+
UART.run_on_each_char(callback, :UART1)
|
428
|
+
|
429
|
+
# Run callback for every 3 characters read
|
430
|
+
UART.run_on_each_chars(callback, :UART1, 3)
|
431
|
+
|
432
|
+
# Run callback for every line read
|
433
|
+
UART.run_on_each_line(callback, :UART1)
|
434
|
+
|
435
|
+
# Run callback once after a character is read
|
436
|
+
UART.run_once_on_each_char(callback, :UART1)
|
437
|
+
|
438
|
+
# Run callback once after 3 characters are read
|
439
|
+
UART.run_once_on_each_chars(callback, :UART1, 3)
|
440
|
+
|
441
|
+
# Run callback once after reading a line
|
442
|
+
UART.run_once_on_each_line(callback, :UART1)
|
443
|
+
|
444
|
+
# Stop the currently running background thread
|
445
|
+
UART.stop_read_wait(:UART1)
|
446
|
+
```
|
447
|
+
|
448
|
+
### I2C
|
449
|
+
The beaglebone has a number of I2C devices. These operate at 3.3v. Do not provide more than 3.3v to the pins or risk damaging the hardware.
|
450
|
+
|
451
|
+
To initialize the I2C device **I2C2**, pass the symbol for that device to the **I2C.setup** method.
|
452
|
+
|
453
|
+
```ruby
|
454
|
+
# Initialize I2C device I2C2
|
455
|
+
I2CDevice.setup(:I2C2)
|
456
|
+
```
|
457
|
+
|
458
|
+
#### I2C Writing
|
459
|
+
To write to an I2C device, the method **I2C.write** is used.
|
460
|
+
|
461
|
+
**I2C.write** takes the following arguments.
|
462
|
+
- i2c: symbol of the I2C device to write to
|
463
|
+
- address: address of slave device
|
464
|
+
- data: data to write
|
465
|
+
|
466
|
+
#### I2C Reading
|
467
|
+
To read from an I2C device, the method **I2C.read** is used.
|
468
|
+
|
469
|
+
**I2C.read** takes the following arguments.
|
470
|
+
- i2c: symbol of the I2C device to read from
|
471
|
+
- address: address of slave device
|
472
|
+
- bytes: bytes to read
|
473
|
+
- register: (optional) register to start reading from
|
474
|
+
|
475
|
+
#### LSM303DLHC Example
|
476
|
+
|
477
|
+
This example communicates with an [LSM303DLHC](https://www.adafruit.com/products/1120) Accelerometer/Compass/Thermometer device.
|
478
|
+
|
479
|
+
```ruby
|
480
|
+
#!/usr/bin/env ruby
|
481
|
+
require 'beaglebone'
|
482
|
+
include Beaglebone
|
483
|
+
|
484
|
+
# Initialize I2C device I2C2
|
485
|
+
I2CDevice.setup(:I2C2)
|
486
|
+
|
487
|
+
# Put compass into continuous conversation mode
|
488
|
+
I2C.write(:I2C2, 0x1e, [0x02, 0x00].pack("C*"))
|
489
|
+
|
490
|
+
# Enable temperatuer sensor, 15hz register update
|
491
|
+
I2C.write(:I2C2, 0x1e, [0x00, 0b10010000].pack("C*") )
|
492
|
+
|
493
|
+
# Delay for the settings to take effect
|
494
|
+
sleep(0.1)
|
495
|
+
|
496
|
+
# Read axis data. It is made up of 3 big endian signed shorts starting at register 0x03
|
497
|
+
raw = I2C.read(:I2C2, 0x1e, 6, [0x03].pack("C*"))
|
498
|
+
|
499
|
+
# Coordinates are big endian signed shorts in x,z,y order
|
500
|
+
x,z,y = raw.unpack("s>*")
|
501
|
+
|
502
|
+
# Calculate angle of degrees from North
|
503
|
+
degrees = (Math::atan2(y, x) * 180) / Math::PI
|
504
|
+
degrees += 360 if degrees < 0
|
505
|
+
|
506
|
+
# Read 2 byte big endian signed short from temperature register
|
507
|
+
raw = I2C.read(:I2C2, 0x1e, 2, [0x31].pack("C*"))
|
508
|
+
|
509
|
+
# Temperature is sent big endian, least significant digit last
|
510
|
+
temp = raw.unpack("s>").first
|
511
|
+
|
512
|
+
# Temperature data is 12 bits, last 4 are unused
|
513
|
+
temp = temp >> 4
|
514
|
+
|
515
|
+
# Each bit is 8c
|
516
|
+
temp /= 8
|
517
|
+
|
518
|
+
# Correction factor
|
519
|
+
temp += 18
|
520
|
+
|
521
|
+
# Convert to f
|
522
|
+
temp = (temp * 1.8 + 32).to_i
|
523
|
+
|
524
|
+
# Output data
|
525
|
+
puts "#{Time.now.strftime("%H:%M")} Temperature: #{temp} degrees f Direction: #{degrees.to_i} degrees"
|
526
|
+
|
527
|
+
# Disable I2C device
|
528
|
+
I2C.disable(:I2C2)
|
529
|
+
```
|
530
|
+
|
531
|
+
### SPI
|
532
|
+
The beaglebone has a number of SPI devices. These operate at 3.3v. Do not provide more than 3.3v to the pins or risk damaging the hardware.
|
533
|
+
|
534
|
+
To initialize the SPI device **SPI0**, pass the symbol for that device to the **SPI.setup** method.
|
535
|
+
|
536
|
+
The optional arguments are also available
|
537
|
+
- mode: SPI mode, :SPI_MODE_0 through :SPI_MODE_3
|
538
|
+
- speed: Speed of the SPI device
|
539
|
+
- bpw: Bits per word
|
540
|
+
|
541
|
+
```ruby
|
542
|
+
# Initialize SPI device SPI0
|
543
|
+
SPI.setup(:SPI0, :SPI_MODE_0, 1000000, 8)
|
544
|
+
|
545
|
+
# You can change SPI with the methods below.
|
546
|
+
|
547
|
+
# Set mode of SPI0
|
548
|
+
SPI.set_mode(:SPI0, :SPI_MODE_3)
|
549
|
+
|
550
|
+
# Set speed of SPI0
|
551
|
+
SPI.set_speed(:SPI0, 100000)
|
552
|
+
|
553
|
+
# Set bits per word of SPI0
|
554
|
+
SPI.set_bpw(:SPI0, 10)
|
555
|
+
|
556
|
+
# Disable SPI device
|
557
|
+
SPI.disable(:SPI0)
|
558
|
+
```
|
559
|
+
|
560
|
+
#### SPI Data Transfer
|
561
|
+
To transfer data to an SPI device, the method **SPI.xfer** is used.
|
562
|
+
|
563
|
+
**SPI.xfer** takes the following arguments
|
564
|
+
- spi: symbol for the SPI device to use
|
565
|
+
- tx_data: data to transmit
|
566
|
+
- readbytes: (optional) number of bytes to read, otherwise it sizeof tx_data is used
|
567
|
+
- speed: (optional) speed of the transfer
|
568
|
+
- delay: (optional) delay
|
569
|
+
- bpw: (optonal) bits per word
|
570
|
+
|
571
|
+
**SPI.xfer** returns the data read from the SPI device.
|
572
|
+
|
573
|
+
#### MCP3008 Example
|
574
|
+
This example communicates with an [MCP3008](http://www.adafruit.com/products/856) ADC device.
|
575
|
+
|
576
|
+
```ruby
|
577
|
+
#!/usr/bin/env ruby
|
578
|
+
require 'beaglebone'
|
579
|
+
include Beaglebone
|
580
|
+
|
581
|
+
# Initialize SPI device SPI0
|
582
|
+
SPIDevice.new(:SPI0)
|
583
|
+
|
584
|
+
# communicate with MCP3008
|
585
|
+
# byte 1: start bit
|
586
|
+
# byte 2: single(1)/diff(0),3 bites for channel, null pad
|
587
|
+
# byte 3: don't care
|
588
|
+
# Read value from channel 0
|
589
|
+
raw = SPI.xfer(:SPI0, [ 0b00000001, 0b10000000, 0].pack("C*"))
|
590
|
+
|
591
|
+
# Split data read into an array of characters
|
592
|
+
data = raw.unpack("C*")
|
593
|
+
|
594
|
+
# The returned data is stored starting at the last two bits of the second byte
|
595
|
+
val = ((data[1] & 0b00000011) << 8 ) | data[2]
|
596
|
+
|
597
|
+
# Display the value of channel 0
|
598
|
+
puts "Value of channel 0: #{val}"
|
599
|
+
|
600
|
+
# Read value from channel 1
|
601
|
+
raw = SPI.xfer(:SPI0, [ 0b00000001, 0b10010000, 0].pack("C*"))
|
602
|
+
|
603
|
+
# Split data read into an array of characters
|
604
|
+
data = raw.unpack("C*")
|
605
|
+
|
606
|
+
# The returned data is stored starting at the last two bits of the second byte
|
607
|
+
val = ((data[1] & 0b00000011) << 8 ) | data[2]
|
608
|
+
|
609
|
+
# Display the value of channel 1
|
610
|
+
puts "Value of channel 1: #{val}"
|
611
|
+
|
612
|
+
# Disable SPI device
|
613
|
+
SPI.disable(:SPI0)
|
614
|
+
```
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: beaglebone
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rob Mosher
|
@@ -19,13 +19,6 @@ files:
|
|
19
19
|
- LICENSE
|
20
20
|
- README.md
|
21
21
|
- beaglebone.gemspec
|
22
|
-
- examples/ain.rb
|
23
|
-
- examples/gpio.rb
|
24
|
-
- examples/i2c.rb
|
25
|
-
- examples/pwm.rb
|
26
|
-
- examples/shiftregister.rb
|
27
|
-
- examples/spi.rb
|
28
|
-
- examples/uart.rb
|
29
22
|
- lib/beaglebone.rb
|
30
23
|
- lib/beaglebone/ain.rb
|
31
24
|
- lib/beaglebone/beaglebone.rb
|
@@ -35,6 +28,7 @@ files:
|
|
35
28
|
- lib/beaglebone/shiftregister.rb
|
36
29
|
- lib/beaglebone/spi.rb
|
37
30
|
- lib/beaglebone/uart.rb
|
31
|
+
- procedural-examples.md
|
38
32
|
homepage: https://github.com/notnyt/beaglebone
|
39
33
|
licenses:
|
40
34
|
- GPL-3.0
|