piface 0.3.1 → 0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5219d7765054be32e631d3fd3cb1ab59d8f4b11b
4
- data.tar.gz: fd6d6999a89eb8c8ad9df17525bc8e3ec31ad006
3
+ metadata.gz: 62414175fab73d83fa196972a27b8178bc4646af
4
+ data.tar.gz: 85b434904389380c0574cc7023037eeaec645fdd
5
5
  SHA512:
6
- metadata.gz: acc2bd5290e6c98cd558511081463bfd7059cd8a094b07d31ff51539929bb8fd5306b5cc6e5db781a6c790b6899b08c6d33e85eeda9f18cb2a807fa06fa029be
7
- data.tar.gz: adbc64f4d580b2ac6e53705d8c2c24485bdab28780272a8f6ae2c519730def47d649266c82b555f06977c4d5a88eae6ee83c753c5224c44acc372ca3544eb1aa
6
+ metadata.gz: 4559d83b88665b759c2de81849bf859e9733bdd80551dbafc54662d7b9587c3348eb7e6f5ccb54d6b2468fe3c48cc5e940001ef9651ec9c9843db727d2d571b5
7
+ data.tar.gz: 4f1dea3ef063bdb39ef88d70bc1a215ff06a4cbb4e46fdcdf83940b2696c4304ce00c71614b629748c0ae35b42045124167d0b971b040e82b2508421a702169a
data/CHANGELOG.md CHANGED
@@ -3,6 +3,13 @@
3
3
  ## Upcoming v1.0
4
4
  - Interrupts (change, high, low)
5
5
 
6
+ ## v0.4.beta
7
+ - update ffi runtime dependancy to ~> v1.7
8
+ - updated README.md
9
+ - added pfio C library as gem extension
10
+ - updated pfio C library to allow optional pin setup (false by default)
11
+ - fixed deinit bug
12
+
6
13
  ## v0.31
7
14
  - updated the ffi load paths (bugfix for issue #1)
8
15
 
data/README.md CHANGED
@@ -9,10 +9,10 @@ Ruby method names, as well as other aspects, may change until version 1.0 is rel
9
9
 
10
10
  The PiFace has 8 inputs and 8 outputs. Both the inputs and outputs are linked to connectors 1-8 respectfully.
11
11
 
12
- Note: The pfio C library will set all outputs to LOW (zero) when first initialized.
12
+ Note: By default, the input and output pins will not be reset when first initialized. To find out more, see [Piface Initialization](https://github.com/blakejakopovic/piface#piface-initialisation).
13
13
 
14
14
  ### Using Outputs
15
- Writing to outputs 1 to 8 with all turn on the LEDs. Write to outputs using Piface::LOW (or 0) for off/disable and Piface::HIGH (or 1) for on/enable.
15
+ Writing to outputs 1 to 8 with all turn on the LEDs. Write to outputs using `Piface::LOW` (or 0) for off/disable and `Piface::HIGH` (or 1) for on/enable.
16
16
 
17
17
  Please note that the PiFace outputs are all open-collectors (meaning that they do not output any voltage). Please read the [PiFace Manual](http://www.farnell.com/datasheets/1684425.pdf) for more information.
18
18
 
@@ -43,7 +43,7 @@ Piface.write 1, 0
43
43
  ```
44
44
 
45
45
  ### Using Classes
46
- Sometimes it's nice to represent an output using a class. One common example is when you want to track the current state of the output.
46
+ Sometimes it's nice to represent an output using a class. One common example is when you want to track the current state of the output. Also see the [Stateless Relay Class](https://github.com/blakejakopovic/piface#stateless-relay-class)
47
47
  ```ruby
48
48
  require 'piface'
49
49
 
@@ -107,6 +107,71 @@ loop do
107
107
  end
108
108
  ```
109
109
 
110
+ ## Advanced Usage
111
+
112
+ ### Piface Initialization
113
+ By requiring the gem, your Piface will automatically be initialized. By default, your pins will not be reset and will remain in the existing state. This is useful when running multiple scripts and you don't want to reset the outputs (turning them all off). If you want to setup the pins you can do so by calling the `init` method with `true`.
114
+ ```ruby
115
+ require 'piface'
116
+
117
+ # Initialize the piface (without setting up the pins)
118
+ Piface.init # same as Piface.init(false)
119
+
120
+ # Initialize Piface and setup the pins
121
+ Piface.init(true)
122
+ ```
123
+
124
+ ### Reading Output
125
+ If you need to check whether or not an output is active, you can easily read an output state with the `read_output` method.
126
+ ```ruby
127
+ require 'piface'
128
+
129
+ # Read the current output of pin 8 (when off)
130
+ Piface.read_output 8
131
+ # => 0
132
+
133
+ # Read the current output of pin 2 (when on)
134
+ Piface.read_output 2
135
+ # => 1
136
+ ```
137
+
138
+ ### Stateless Relay class
139
+ If you have multiple scripts running, it can be hard to keep track of output states. By using a stateless class, you can implement a toggle method that reads the current state, instead of using a stored state. Keep in mind that by reading the state is it less effecient.
140
+ ```ruby
141
+ require 'piface'
142
+
143
+ class Relay
144
+ def initialize(relay_number)
145
+ @relay_number = relay_number
146
+ end
147
+
148
+ def turn_on
149
+ Piface.write @relay_number, 1
150
+ end
151
+
152
+ def turn_off
153
+ Piface.write @relay_number, 0
154
+ end
155
+
156
+ def toggle
157
+ Piface.write @relay_number, Piface.read_output(1) ^ 1
158
+ end
159
+ end
160
+
161
+ relay2 = Relay.new(2)
162
+ relay.toggle # toggle the light without using a stored state
163
+ ```
164
+
165
+ ## Examples
166
+ For more examples, check out the `example` directory.
167
+ * led
168
+ * pir sensor
169
+ * relay (same as stateless relay)
170
+ * toggle button
171
+
172
+ ## Example Projects
173
+ * [Siriproxy Piface](https://github.com/elvisimprsntr/siriproxy-piface) - "I used my RPi, PiFace IO board, along with SiriProry as a simple voice controlled garage door opener."
174
+
110
175
  ## Additional Resources
111
176
  * [The PiFace Digital PDF Manual](http://www.farnell.com/datasheets/1684425.pdf)
112
177
  * [pfio C Library](https://github.com/thomasmacpherson/piface/blob/master/c/)
@@ -114,13 +179,10 @@ end
114
179
 
115
180
  ## Installation
116
181
 
117
- First install the pfio C Library
118
-
119
- [https://github.com/thomasmacpherson/piface](https://github.com/thomasmacpherson/piface)
120
-
121
- Enable RaspberryPi's SPI module
182
+ Enable RaspberryPi's SPI module (required on each reboot)
122
183
 
123
- $ gpio load spi
184
+ $ sudo modprobe spi_bcm2708
185
+ $ sudo chown `id -u`.`id -g` /dev/spidev0.*
124
186
 
125
187
  Add this line to your application's Gemfile:
126
188
 
data/examples/led.rb ADDED
@@ -0,0 +1,33 @@
1
+ # piface/examples/led.rb
2
+
3
+ require 'piface'
4
+
5
+ class LED
6
+ def initialize(pin_number)
7
+ @pin_number = pin_number
8
+ end
9
+
10
+ def turn_on
11
+ Piface.write @pin_number, 1
12
+ end
13
+
14
+ def turn_off
15
+ Piface.write @pin_number, 0
16
+ end
17
+
18
+ def state
19
+ Piface.read_output(@pin_number)
20
+ end
21
+
22
+ def toggle
23
+ new_state = state ^ 1
24
+ Piface.write @pin_number, new_state
25
+ end
26
+
27
+ def blink(times = 1)
28
+ 0.upto(times * 2) do
29
+ toggle
30
+ sleep 0.25
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,12 @@
1
+ # piface/examples/pir_sensor.rb
2
+
3
+ require 'piface'
4
+
5
+ SENSOR_PIN = 5
6
+
7
+ puts "Waiting for motion..."
8
+ while Piface.read(SENSOR_PIN) == 1
9
+ sleep 0.5
10
+ end
11
+
12
+ puts "MOTION DETECTED"
data/examples/relay.rb ADDED
@@ -0,0 +1,29 @@
1
+ # piface/examples/relay.rb
2
+
3
+ require 'piface'
4
+
5
+ class Relay
6
+ def initialize(relay_number)
7
+ @relay_number = relay_number
8
+ end
9
+
10
+ def turn_on
11
+ Piface.write @relay_number, 1
12
+ end
13
+
14
+ def turn_off
15
+ Piface.write @relay_number, 0
16
+ end
17
+
18
+ def state
19
+ Piface.read_output(@relay_number)
20
+ end
21
+
22
+ def toggle
23
+ new_state = state ^ 1
24
+ Piface.write @relay_number, new_state
25
+ end
26
+ end
27
+
28
+ relay2 = Relay.new(2)
29
+ relay.toggle # toggle the light without using a stored state
@@ -0,0 +1,43 @@
1
+ # piface/examples/toggle_button.rb
2
+
3
+ require 'piface'
4
+
5
+ class ToggleButton
6
+
7
+ LOW = 0
8
+ HIGH = 1
9
+
10
+ def initialize(pin_number)
11
+ @pin_number = pin_number
12
+ @thread = nil
13
+ end
14
+
15
+ def toggle
16
+ new_state = Piface.read_output(@pin_number) ^ 1
17
+ Piface.write(@pin_number, new_state)
18
+ end
19
+
20
+ def read_pin
21
+ Piface.read(@pin_number)
22
+ end
23
+
24
+ def activate
25
+ @thread = Thread.new do
26
+ loop do
27
+ if read_pin == LOW
28
+ toggle
29
+ sleep 0.1 while read_pin == LOW # wait until released
30
+ end
31
+
32
+ sleep 0.05
33
+ end
34
+ end
35
+ end
36
+
37
+ def deactivate
38
+ Thread.kill(@thread) if @thread
39
+ end
40
+ end
41
+
42
+ # button = ToggleButton.new(2)
43
+ # button.activate
@@ -0,0 +1,3 @@
1
+ require 'mkmf'
2
+
3
+ create_makefile('piface/pfio')
data/ext/piface/pfio.c ADDED
@@ -0,0 +1,189 @@
1
+ /**
2
+ * pfio.c
3
+ * functions for accessing the PiFace add-on for the Raspberry Pi
4
+ */
5
+ #include "pfio.h"
6
+
7
+ #undef VERBOSE_MODE
8
+
9
+ static Spi * spi;
10
+
11
+ static void spi_transfer(char * txbuffer, char * rxbuffer);
12
+ static void spi_write(char port, char value);
13
+ static char spi_read(char port);
14
+
15
+
16
+ // char pfio_init(void)
17
+ char pfio_init(bool setup_pins)
18
+ {
19
+ if ((spi = malloc(sizeof(Spi))) == NULL)
20
+ return -1;
21
+
22
+ // initialise the spi with some values
23
+ // create the path string
24
+ char path[MAXPATH];
25
+ if (snprintf(path, MAXPATH, "/dev/spidev%d.%d", SPI_BUS, SPI_DEVICE) >= MAXPATH)
26
+ {
27
+ fprintf(stderr, "ERROR: Bus and/or device number is invalid.");
28
+ return -1;
29
+ }
30
+
31
+ // try to open the device
32
+ if ((spi->fd = open(path, O_RDWR, 0)) < 0)
33
+ {
34
+ fprintf(stderr, "ERROR: Can not open device");
35
+ return -1;
36
+ }
37
+
38
+ // try to control the device
39
+ char temp;
40
+ if (ioctl(spi->fd, SPI_IOC_RD_MODE, &temp) < 0)
41
+ {
42
+ fprintf(stderr, "ERROR: Can not get spi mode");
43
+ return -1;
44
+ }
45
+ spi->mode = temp;
46
+
47
+ // try to get the bits per word
48
+ if (ioctl(spi->fd, SPI_IOC_RD_BITS_PER_WORD, &temp) < 0)
49
+ {
50
+ fprintf(stderr, "ERROR: Can not get bits per word");
51
+ return -1;
52
+ }
53
+ spi->bitsperword = temp;
54
+
55
+ // try to get the max speed
56
+ int maxspeed;
57
+ if (ioctl(spi->fd, SPI_IOC_RD_MAX_SPEED_HZ, &maxspeed) < 0)
58
+ {
59
+ fprintf(stderr, "ERROR: Can not get max speed hz");
60
+ return -1;
61
+ }
62
+ spi->maxspeed = maxspeed;
63
+
64
+ if (setup_pins == true) {
65
+ // set up some ports
66
+ spi_write(IOCON, 8); // enable hardware addressing
67
+ spi_write(IODIRA, 0); // set port A as outputs
68
+ spi_write(IODIRB, 0xFF); // set port B as inputs
69
+ spi_write(GPIOA, 0xFF); // set port A on
70
+ //spi_write(GPIOB, 0xFF); // set port B on
71
+ spi_write(GPPUA, 0xFF); // set port A pullups on
72
+ spi_write(GPPUB, 0xFF); // set port B pullups on
73
+
74
+ // initialise all outputs to 0
75
+ int i;
76
+ for (i = 1; i <= 8; i++)
77
+ pfio_digital_write(i, 0);
78
+ }
79
+
80
+ return 0;
81
+ }
82
+
83
+ char pfio_deinit(void)
84
+ {
85
+ close(spi->fd);
86
+ free(spi);
87
+ return 0;
88
+ }
89
+
90
+ char pfio_digital_read(char pin_number)
91
+ {
92
+ char current_pin_values = pfio_read_input();
93
+ char pin_bit_mask = pfio_get_pin_bit_mask(pin_number);
94
+ return (current_pin_values & pin_bit_mask) > 0;
95
+ }
96
+
97
+ void pfio_digital_write(char pin_number, char value)
98
+ {
99
+ char pin_bit_mask = pfio_get_pin_bit_mask(pin_number);
100
+ char old_pin_values = pfio_read_output();
101
+
102
+ char new_pin_values;
103
+ if (value > 0)
104
+ new_pin_values = old_pin_values | pin_bit_mask;
105
+ else
106
+ new_pin_values = old_pin_values & ~pin_bit_mask;
107
+
108
+ #ifdef VERBOSE_MODE
109
+ printf("digital_write: pin number %d, value %d\n", pin_number, value);
110
+ printf("pin bit mask: 0x%x\n", pin_bit_mask);
111
+ printf("old pin values: 0x%x\n", old_pin_values);
112
+ printf("new pin values: 0x%x\n", new_pin_values);
113
+ printf("\n");
114
+ #endif
115
+
116
+ pfio_write_output(new_pin_values);
117
+ }
118
+
119
+ char pfio_read_input(void)
120
+ {
121
+ return spi_read(INPUT_PORT);
122
+ }
123
+
124
+ char pfio_read_output(void)
125
+ {
126
+ return spi_read(OUTPUT_PORT);
127
+ }
128
+
129
+ void pfio_write_output(char value)
130
+ {
131
+ spi_write(OUTPUT_PORT, value);
132
+ }
133
+
134
+ char pfio_get_pin_bit_mask(char pin_number)
135
+ {
136
+ return 1 << (pin_number-1);
137
+ }
138
+
139
+ char pfio_get_pin_number(char bit_pattern)
140
+ {
141
+ char pin_number = 1; // assume pin 1
142
+ while ((bit_pattern & 1) == 0)
143
+ {
144
+ bit_pattern >>= 1;
145
+ if (++pin_number > 8)
146
+ {
147
+ pin_number = 0;
148
+ break;
149
+ }
150
+ }
151
+ return pin_number;
152
+ }
153
+
154
+
155
+ static void spi_transfer(char * txbuffer, char * rxbuffer)
156
+ {
157
+ // set up some transfer information
158
+ struct spi_ioc_transfer transfer_buffer =
159
+ {
160
+ .tx_buf = (unsigned long) txbuffer,
161
+ .rx_buf = (unsigned long) rxbuffer,
162
+ .len = TRANSFER_LEN,
163
+ .delay_usecs = TRANSFER_DELAY,
164
+ .speed_hz = TRANSFER_SPEED,
165
+ .bits_per_word = TRANSFER_BPW,
166
+ };
167
+
168
+ // actually do the transfer
169
+ if (ioctl(spi->fd, SPI_IOC_MESSAGE(1), &transfer_buffer) < 1)
170
+ {
171
+ fprintf(stderr, "ERROR: Can not send SPI message");
172
+ perror(0);
173
+ }
174
+ }
175
+
176
+ static void spi_write(char port, char value)
177
+ {
178
+ char txbuffer[] = {SPI_WRITE_CMD, port, value};
179
+ char rxbuffer[ARRAY_SIZE(txbuffer)];
180
+ spi_transfer(txbuffer, rxbuffer);
181
+ }
182
+
183
+ static char spi_read(char port)
184
+ {
185
+ char txbuffer[] = {SPI_READ_CMD, port, 0xff};
186
+ char rxbuffer[ARRAY_SIZE(txbuffer)];
187
+ spi_transfer(txbuffer, rxbuffer);
188
+ return rxbuffer[2];
189
+ }
data/ext/piface/pfio.h ADDED
@@ -0,0 +1,66 @@
1
+ /**
2
+ * pfio.h
3
+ * functions for accessing the PiFace add-on for the Raspberry Pi
4
+ */
5
+ #include <stdio.h>
6
+ #include <stdlib.h>
7
+ #include <string.h>
8
+ #include <unistd.h>
9
+ #include <fcntl.h>
10
+ #include <linux/spi/spidev.h>
11
+ #include <linux/types.h>
12
+ #include <sys/ioctl.h>
13
+
14
+ // /dev/spidev<BUS>.<DEVICE>
15
+ #define SPI_BUS 0
16
+ #define SPI_DEVICE 0
17
+ #define MAXPATH 16
18
+
19
+ #define TRANSFER_LEN 3
20
+ #define TRANSFER_DELAY 5
21
+ #define TRANSFER_SPEED 1000000
22
+ #define TRANSFER_BPW 8
23
+
24
+ #define SPI_WRITE_CMD 0x40
25
+ #define SPI_READ_CMD 0x41
26
+
27
+ // Port configuration
28
+ #define IODIRA 0x00 // I/O direction A
29
+ #define IODIRB 0x01 // I/O direction B
30
+ #define IOCON 0x0A // I/O config
31
+ #define GPIOA 0x12 // port A
32
+ #define GPIOB 0x13 // port B
33
+ #define GPPUA 0x0C // port A pullups
34
+ #define GPPUB 0x0D // port B pullups
35
+ #define OUTPUT_PORT GPIOA
36
+ #define INPUT_PORT GPIOB
37
+
38
+ #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
39
+
40
+
41
+ typedef struct
42
+ {
43
+ int fd; // open file descriptor: /dev/spi-X.Y
44
+ int mode; // current SPI mode
45
+ int bitsperword; // current SPI bits per word setting
46
+ int maxspeed; // current SPI max speed setting in Hz
47
+ } Spi;
48
+
49
+ typedef enum { false, true } bool;
50
+
51
+ // extern char pfio_init(void);
52
+ extern char pfio_init(bool setup_pins);
53
+ extern char pfio_deinit(void);
54
+ extern char pfio_digital_read(char pin_number);
55
+ extern void pfio_digital_write(char pin_number, char value);
56
+ extern char pfio_read_input(void);
57
+ extern char pfio_read_output(void);
58
+ extern void pfio_write_output(char value);
59
+ extern char pfio_get_pin_bit_mask(char pin_number);
60
+ extern char pfio_get_pin_number(char bit_mask);
61
+
62
+ /*
63
+ static void spi_transfer(char * txbuffer, char * rxbuffer);
64
+ static void spi_write(char port, char value);
65
+ static char spi_read(char port);
66
+ */
data/lib/piface.rb CHANGED
@@ -24,12 +24,12 @@ module Piface
24
24
  end
25
25
 
26
26
  private
27
- def self.init
28
- Native.pfio_init
27
+ def self.init(setup_pins = false)
28
+ Native.pfio_init(setup_pins)
29
29
  end
30
30
 
31
31
  def self.deinit
32
- Native.pfio_init
32
+ Native.pfio_deinit
33
33
  end
34
34
 
35
35
  def self.pin_number_to_flag(pin_number)
data/lib/piface/native.rb CHANGED
@@ -3,9 +3,9 @@ require "ffi"
3
3
  module Piface
4
4
  module Native
5
5
  extend FFI::Library
6
- ffi_lib ['libpiface', 'libpiface-1.0', 'libpiface-1.0.so', '/usr/local/lib/libpiface-1.0.so']
6
+ ffi_lib File.expand_path("../pfio.so", __FILE__)
7
7
 
8
- attach_function :pfio_init, [], :char
8
+ attach_function :pfio_init, [ :bool ], :char
9
9
  attach_function :pfio_deinit, [], :char
10
10
 
11
11
  attach_function :pfio_digital_read, [ :char ], :char
@@ -1,3 +1,3 @@
1
1
  module Piface
2
- VERSION = "0.3.1"
2
+ VERSION = "0.4"
3
3
  end
data/piface.gemspec CHANGED
@@ -10,16 +10,15 @@ Gem::Specification.new do |spec|
10
10
  spec.email = ["blake.jakopovic@gmail.com"]
11
11
  spec.description = %q{Ruby gem for using PiFace Extension Board (and Raspberry Pi)}
12
12
  spec.summary = %q{Ruby Bindings for the pfio.c C Library for use with the PiFace Digital extension board and your Raspberry Pi}
13
- spec.homepage = "http://twitter.com/blakejakopovic"
13
+ spec.homepage = "https://github.com/blakejakopovic/piface"
14
14
  spec.license = "MIT"
15
15
 
16
16
  spec.files = `git ls-files`.split($/)
17
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
17
+ spec.extensions = ['ext/piface/extconf.rb']
19
18
  spec.require_paths = ["lib"]
20
19
 
21
20
  spec.add_development_dependency "bundler", "~> 1.3"
22
21
  spec.add_development_dependency "rake"
23
22
 
24
- spec.add_dependency "ffi", "~> 1.7.dev"
23
+ spec.add_dependency "ffi", "~> 1.7"
25
24
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: piface
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: '0.4'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Blake Jakopovic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-04-04 00:00:00.000000000 Z
11
+ date: 2013-04-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -44,19 +44,20 @@ dependencies:
44
44
  requirements:
45
45
  - - ~>
46
46
  - !ruby/object:Gem::Version
47
- version: 1.7.dev
47
+ version: '1.7'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ~>
53
53
  - !ruby/object:Gem::Version
54
- version: 1.7.dev
54
+ version: '1.7'
55
55
  description: Ruby gem for using PiFace Extension Board (and Raspberry Pi)
56
56
  email:
57
57
  - blake.jakopovic@gmail.com
58
58
  executables: []
59
- extensions: []
59
+ extensions:
60
+ - ext/piface/extconf.rb
60
61
  extra_rdoc_files: []
61
62
  files:
62
63
  - .gitignore
@@ -65,11 +66,18 @@ files:
65
66
  - LICENSE.txt
66
67
  - README.md
67
68
  - Rakefile
69
+ - examples/led.rb
70
+ - examples/pir_sensor.rb
71
+ - examples/relay.rb
72
+ - examples/toggle_button.rb
73
+ - ext/piface/extconf.rb
74
+ - ext/piface/pfio.c
75
+ - ext/piface/pfio.h
68
76
  - lib/piface.rb
69
77
  - lib/piface/native.rb
70
78
  - lib/piface/version.rb
71
79
  - piface.gemspec
72
- homepage: http://twitter.com/blakejakopovic
80
+ homepage: https://github.com/blakejakopovic/piface
73
81
  licenses:
74
82
  - MIT
75
83
  metadata: {}