pigpio 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,23 @@
1
+ require "pigpio"
2
+ include Pigpio::Constant
3
+ pi=Pigpio.new()
4
+ unless pi.connect
5
+ exit -1
6
+ end
7
+ counter=0
8
+ led=pi.gpio(4)
9
+ led.mode=PI_OUTPUT
10
+ led.pud=PI_PUD_OFF
11
+
12
+ button=pi.gpio(17)
13
+ button.mode=PI_INPUT
14
+ button.pud=PI_PUD_UP
15
+ button.glitch_filter(30)
16
+ button.callback(EITHER_EDGE){|tick,level|
17
+ led.write level
18
+ counter+=1
19
+ }
20
+
21
+ while(counter<10)do
22
+ end
23
+ led.write 0
@@ -0,0 +1,21 @@
1
+ require "pigpio"
2
+ include Pigpio::Constant
3
+ pi=Pigpio.new()
4
+ unless pi.connect
5
+ exit -1
6
+ end
7
+ pin=pi.gpio(4)
8
+ pin.mode=PI_OUTPUT
9
+ pin.pud=PI_PUD_OFF
10
+ pwm=pin.pwm
11
+
12
+ button=pi.gpio(17)
13
+ button.mode=PI_INPUT
14
+ button.pud=PI_PUD_UP
15
+
16
+ i=128
17
+ while true do
18
+ i=(i+1)%256 if button.read == 0
19
+ pwm.dutycycle= i
20
+ sleep 0.01
21
+ end
@@ -0,0 +1,27 @@
1
+ # Simple IO sample
2
+
3
+ ## Board
4
+
5
+ ![board_image](./board.svg)
6
+
7
+ ## PWM sample
8
+
9
+ [Script is here.](./pwm.rb)
10
+
11
+ LED brightness will increase while you press the button.
12
+
13
+ ```sh
14
+ $ ruby pwm.rb
15
+ ```
16
+
17
+ ## Callback sample
18
+
19
+ [Script is here.](./callback.rb)
20
+
21
+ not work, now.
22
+
23
+ LED will light, while you press the button.
24
+
25
+ ```sh
26
+ $ ruby callback.rb
27
+ ```
data/ext/pigpio/pigpio.c CHANGED
@@ -6,20 +6,103 @@
6
6
  static VALUE cCallbackID;
7
7
  static VALUE cCallbackError;
8
8
 
9
+ typedef struct{
10
+ unsigned level;
11
+ uint32_t tick;
12
+ } callback_item_t;
13
+
14
+ #define PG_EXT_CALLBACK_BUF_SIZE (128)
15
+ typedef struct{
16
+ volatile callback_item_t buf[ PG_EXT_CALLBACK_BUF_SIZE ];
17
+ volatile callback_item_t* volatile read;
18
+ volatile callback_item_t* volatile write;
19
+ volatile int flag_overflow;
20
+ } callback_queue_t;
21
+
22
+
23
+
24
+ typedef struct{
25
+ callback_queue_t*queue;
26
+ } callback_pqueue_t;
27
+ void pigpio_rbst_callback_que_dfree(void* _self){
28
+ callback_pqueue_t *self=(callback_pqueue_t *)_self;
29
+ if(self->queue!=NULL)free(self->queue);
30
+ xfree(self);
31
+ return;
32
+ }
33
+ size_t pigpio_rbst_callback_que_dsize(const void *_self){
34
+ return sizeof(callback_pqueue_t)+sizeof(callback_queue_t);
35
+ }
36
+ const rb_data_type_t callback_pqueue_type = { //https://gist.github.com/yugui/87ef6964d8a76794be6f
37
+ "struct@callback_pqueue",{NULL,pigpio_rbst_callback_que_dfree,pigpio_rbst_callback_que_dsize,{0,0}},0,NULL,0
38
+ };
39
+ /*
40
+ Constructor of Pigpio::NativeQueue class
41
+ */
42
+ VALUE pigpio_rbst_callback_pqueue_make(VALUE self){
43
+ VALUE obj;
44
+ callback_pqueue_t *st;
45
+ callback_queue_t *queue;
46
+ obj = TypedData_Make_Struct(self, callback_pqueue_t, &callback_pqueue_type, st);
47
+ st->queue=queue=malloc(sizeof(callback_queue_t));
48
+ queue->read=queue->buf;
49
+ queue->write=queue->buf;
50
+ queue->flag_overflow=0;
51
+ return obj;
52
+ }
53
+ /*
54
+ Get a data from FIFO Queue.
55
+ */
56
+ VALUE pigpio_rbst_callback_pqueue_pop(VALUE self){
57
+ callback_pqueue_t *st=TypedData_Get_Struct2(self,callback_pqueue_t,&callback_pqueue_type);
58
+ callback_queue_t *queue=st->queue;
59
+ volatile callback_item_t *cur=queue->read;
60
+ VALUE ret;
61
+ struct timeval t;
62
+ t.tv_usec=100000;
63
+ if(queue->flag_overflow!=0){
64
+ rb_raise(cCallbackError,"Overflow NativeQueue.\n");
65
+ }
66
+ while(cur==queue->write){
67
+ rb_thread_wait_for(t);
68
+ }
69
+ ret=rb_ary_new_from_args(2,ULONG2NUM(cur->tick),UINT2NUM(cur->level));
70
+ queue->read=(cur==queue->buf+(PG_EXT_CALLBACK_BUF_SIZE-1)) ? queue->buf : (cur+1) ;
71
+ return(ret);
72
+ }
73
+ /*
74
+ Set a data to FIFO Queue.
75
+ */
76
+ void pigpio_rbstn_callback_pqueue_push(callback_queue_t *queue,unsigned level, uint32_t tick){
77
+ volatile callback_item_t *cur=queue->write;
78
+ cur->tick=tick;
79
+ cur->level=level;
80
+ cur=(cur==queue->buf+(PG_EXT_CALLBACK_BUF_SIZE-1)) ? queue->buf : (cur+1) ;
81
+ if(cur==queue->read){
82
+ queue->flag_overflow=1;
83
+ }else{
84
+ queue->write=cur;
85
+ }
86
+ return;
87
+ }
9
88
 
10
89
  typedef int (*cancel_t)(unsigned);
11
90
  typedef struct{
12
91
  int id;
13
- VALUE proc;
92
+ VALUE queue;
93
+ VALUE thread;
14
94
  cancel_t cancel;
15
95
  } callback_id_t;
96
+
16
97
  void pigpio_rbst_callback_id_dmark(void* _self){
17
98
  callback_id_t *self=(callback_id_t *)_self;
18
- rb_gc_mark(self->proc);
99
+ rb_gc_mark(self->queue);
100
+ rb_gc_mark(self->thread);
19
101
  }
20
102
  void pigpio_rbst_callback_id_dfree(void* _self){
21
103
  callback_id_t *self=(callback_id_t *)_self;
22
104
  xfree(self);
105
+ return;
23
106
  }
24
107
  size_t pigpio_rbst_callback_id_dsize(const void *_self){
25
108
  return sizeof(callback_id_t);
@@ -32,17 +115,19 @@ const rb_data_type_t callback_id_data_type = { //https://gist.github.com/yugui/8
32
115
  {0,0}
33
116
  },0,NULL,0
34
117
  };
35
- VALUE pigpio_rbst_callback_id_make_inner(int id,VALUE proc,cancel_t cancel){
118
+ VALUE pigpio_rbst_callback_id_make_inner(int id,cancel_t cancel,VALUE queue,VALUE thread){
36
119
  VALUE obj;
37
120
  callback_id_t *st;
38
121
  obj = TypedData_Make_Struct(cCallbackID, callback_id_t, &callback_id_data_type, st);
39
122
  st->id=id;
40
- st->proc=proc;
123
+ st->queue=queue;
124
+ st->thread=thread;
41
125
  st->cancel=cancel;
126
+
42
127
  return obj;
43
128
  }
44
129
  /*
45
- get callback id.return Integer.
130
+ Get callback id.R eturn Integer.
46
131
  */
47
132
  VALUE pigpio_rbst_callback_id_r_id(VALUE self){
48
133
  callback_id_t *st=TypedData_Get_Struct2(self,callback_id_t,&callback_id_data_type);
@@ -60,9 +145,25 @@ See also: {pigpio site event_callback_cancel}[http://abyz.me.uk/rpi/pigpio/pdif2
60
145
  See also: {pigpio site callback_cancel}[http://abyz.me.uk/rpi/pigpio/pdif2.html#callback_cancel]
61
146
  */
62
147
  VALUE pigpio_rbst_callback_id_cancel(VALUE self){
148
+ int id;
63
149
  callback_id_t *st=TypedData_Get_Struct2(self,callback_id_t,&callback_id_data_type);
64
- if(st->id<0){return INT2NUM(pigif_callback_not_found);}
65
- return INT2NUM((*(st->cancel))(st->id));
150
+ id=st->id;
151
+ if(id<0){return INT2NUM(pigif_callback_not_found);}
152
+ if(st->thread!=Qnil){
153
+ rb_funcall((VALUE)st->thread, rb_intern("kill"), 0);
154
+ }
155
+ st->id=-1;
156
+ st->thread=Qnil;
157
+ st->queue=Qnil;
158
+ return INT2NUM((*(st->cancel))(id));
159
+ }
160
+ void pigpio_rbbk_CBFuncEx(int pi, unsigned user_gpio, unsigned level, uint32_t tick, void *queue){
161
+ pigpio_rbstn_callback_pqueue_push((callback_queue_t *)queue,level,tick);
162
+ return;
163
+ }
164
+ void pigpio_rbbk_evtCBFuncEx(int pi, unsigned event, uint32_t tick, void *callee_proc){
165
+ (rb_funcall((VALUE)callee_proc, rb_intern("call"), 2,ULONG2NUM(tick),UINT2NUM(event)));
166
+ return;
66
167
  }
67
168
 
68
169
  const rb_data_type_t bsc_xfer_data_type = { //https://gist.github.com/yugui/87ef6964d8a76794be6f
@@ -144,14 +245,6 @@ VALUE pigpio_rbst_gpioPulse_make(VALUE self,VALUE gpioOn,VALUE gpioOff,VALUE usD
144
245
  st->usDelay=NUM2ULONG(usDelay);
145
246
  return obj;
146
247
  }
147
- void pigpio_rbbk_CBFuncEx(int pi, unsigned user_gpio, unsigned level, uint32_t tick, void *userdata){
148
- (rb_funcall((VALUE)userdata, rb_intern("call"), 3,ULONG2NUM(tick),UINT2NUM(level),UINT2NUM(user_gpio)));
149
- return;
150
- }
151
- void pigpio_rbbk_evtCBFuncEx(int pi, unsigned event, uint32_t tick, void *userdata){
152
- (rb_funcall((VALUE)userdata, rb_intern("call"), 2,ULONG2NUM(tick),UINT2NUM(event)));
153
- return;
154
- }
155
248
 
156
249
  /*
157
250
  Connect to the pigpio daemon. Reserving command and
@@ -1899,13 +1992,13 @@ If you call this method without a block, this method raises an Pigpio::CallbackE
1899
1992
 
1900
1993
  See also: {pigpio site}[http://abyz.me.uk/rpi/pigpio/pdif2.html#callback_ex]
1901
1994
  */
1902
- VALUE pigpio_rbfn_callback(int argc, VALUE *argv, VALUE self){
1995
+ VALUE pigpio_rbfn_callback(VALUE self,VALUE pi, VALUE user_gpio, VALUE edge, VALUE queue, VALUE thread){
1903
1996
  int id;
1904
- VALUE pi; VALUE user_gpio; VALUE edge; VALUE userdata;
1905
- rb_scan_args(argc,argv,"3&",&pi,&user_gpio,&edge,&userdata);
1906
- if(NIL_P(userdata)){rb_raise(cCallbackError,"No callback block.\n");}
1907
- id=( callback_ex(NUM2INT(pi), NUM2UINT(user_gpio), NUM2UINT(edge), pigpio_rbbk_CBFuncEx, (void*)userdata));
1908
- return pigpio_rbst_callback_id_make_inner(id,userdata,callback_cancel);
1997
+ callback_pqueue_t *st=TypedData_Get_Struct2(queue,callback_pqueue_t,&callback_pqueue_type);
1998
+
1999
+ //if(NIL_P(callee_proc)){rb_raise(cCallbackError,"No callback block.\n");}
2000
+ id=callback_ex(NUM2INT(pi), NUM2UINT(user_gpio), NUM2UINT(edge), pigpio_rbbk_CBFuncEx, (void*)st->queue);
2001
+ return pigpio_rbst_callback_id_make_inner(id,callback_cancel,queue,thread);
1909
2002
  }
1910
2003
  /*
1911
2004
  This function cancels a callback identified by its id.
@@ -1921,8 +2014,8 @@ The function returns 0 if OK, otherwise pigif_callback_not_found.
1921
2014
 
1922
2015
  See also: {pigpio site}[http://abyz.me.uk/rpi/pigpio/pdif2.html#callback_cancel]
1923
2016
  */
1924
- VALUE pigpio_rbfn_callback_cancel(VALUE self,VALUE callback_id){
1925
- return INT2NUM( callback_cancel(NUM2UINT(callback_id)));
2017
+ VALUE pigpio_rbfn_callback_cancel(VALUE self,VALUE callback){
2018
+ return INT2NUM( callback_cancel(NUM2UINT(callback)));
1926
2019
  }
1927
2020
  /*
1928
2021
  This function waits for an edge on the GPIO for up to timeout
@@ -1976,11 +2069,10 @@ See also: {pigpio site}[http://abyz.me.uk/rpi/pigpio/pdif2.html#event_callback_e
1976
2069
  */
1977
2070
  VALUE pigpio_rbfn_event_callback(int argc, VALUE *argv, VALUE self){
1978
2071
  int id;
1979
- VALUE pi; VALUE event; VALUE userdata;
1980
- rb_scan_args(argc,argv,"2&",&pi,&event,&userdata);
1981
- if(NIL_P(userdata)){rb_raise(cCallbackError,"No callback block.\n");}
1982
- id=( event_callback_ex(NUM2INT(pi), NUM2UINT(event), pigpio_rbbk_evtCBFuncEx, (void *)userdata));
1983
- return pigpio_rbst_callback_id_make_inner(id,userdata,event_callback_cancel);
2072
+ VALUE pi; VALUE event; VALUE queue; VALUE thread;
2073
+ rb_scan_args(argc,argv,"4",&pi,&event,&queue,&thread);
2074
+ id=event_callback_ex(NUM2INT(pi), NUM2UINT(event), pigpio_rbbk_evtCBFuncEx, (void *)queue);
2075
+ return pigpio_rbst_callback_id_make_inner(id,event_callback_cancel,queue,thread);
1984
2076
  }
1985
2077
  /*
1986
2078
  This function cancels an event callback identified by its id.
@@ -3514,7 +3606,7 @@ VALUE pigpio_rbfn_bsc_i2c(VALUE self, VALUE pi, VALUE i2c_addr, VALUE bscxfer){
3514
3606
  This class has some constances for pigpio library.
3515
3607
  */
3516
3608
  void Init_pigpio(void){
3517
- VALUE cPulse,cBscXfer;
3609
+ VALUE cPulse,cBscXfer,cNativeQueue;
3518
3610
  /*
3519
3611
  This class has some constances for pigpio library.
3520
3612
  */
@@ -3583,7 +3675,7 @@ This class has some constances for pigpio library.
3583
3675
  rb_define_singleton_method(cAPI, "wave_add_generic", pigpio_rbfn_wave_add_generic, 2);
3584
3676
  rb_define_singleton_method(cAPI, "wave_add_serial", pigpio_rbfn_wave_add_serial, 7);
3585
3677
  rb_define_singleton_method(cAPI, "wave_chain", pigpio_rbfn_wave_chain, 2);
3586
- rb_define_singleton_method(cAPI, "callback", pigpio_rbfn_callback, -1);
3678
+ rb_define_singleton_method(cAPI, "callback", pigpio_rbfn_callback, 5);
3587
3679
  rb_define_singleton_method(cAPI, "callback_cancel", pigpio_rbfn_callback_cancel, 1);
3588
3680
  rb_define_singleton_method(cAPI, "wait_for_edge", pigpio_rbfn_wait_for_edge, 4);
3589
3681
  rb_define_singleton_method(cAPI, "event_callback", pigpio_rbfn_event_callback, -1);
@@ -3654,15 +3746,24 @@ This class has some constances for pigpio library.
3654
3746
  rb_define_method(cBscXfer, "control=", pigpio_rbst_bsc_xfer_w_control, 1);
3655
3747
  rb_define_method(cBscXfer, "txBuf=", pigpio_rbst_bsc_xfer_w_txBuf, 1);
3656
3748
  rb_define_method(cBscXfer, "rxBuf", pigpio_rbst_bsc_xfer_r_rxBuf, 0);
3749
+
3657
3750
  /*
3658
- The class for callback.
3751
+ The class of native queue.
3752
+ */
3753
+ cNativeQueue = rb_define_class_under(cPigpio,"NativeQueue", rb_cData);
3754
+ rb_define_singleton_method(cNativeQueue, "make", pigpio_rbst_callback_pqueue_make, 0);
3755
+ rb_define_method(cNativeQueue, "pop", pigpio_rbst_callback_pqueue_pop, 0);
3756
+
3757
+ /*
3758
+ The class of callback.
3659
3759
  */
3660
3760
  cCallbackID = rb_define_class_under(cPigpio,"Callback", rb_cData);
3661
3761
  rb_define_method(cCallbackID, "id", pigpio_rbst_callback_id_r_id, 0);
3662
3762
  rb_define_method(cCallbackID, "cancel", pigpio_rbst_callback_id_cancel, 0);
3663
3763
  rb_gc_register_address(&cCallbackID);
3764
+
3664
3765
  /*
3665
- The class for callback error.
3766
+ The class of callback error.
3666
3767
  */
3667
3768
  cCallbackError = rb_define_class_under(cPigpio,"CallbackError", rb_eException);
3668
3769
  rb_gc_register_address(&cCallbackError);
data/lib/pigpio/bank.rb CHANGED
@@ -1,20 +1,22 @@
1
- class Pigpio::Bank
2
- Set={
3
- read: [:read_bank_1 ,:read_bank_2],
4
- clear: [:clear_bank_1,:clear_bank_2],
5
- set: [:set_bank_1 ,:set_bank_2],
6
- }
7
- def initialize(pi,num)
8
- @pi=pi
9
- @num=num
1
+ class Pigpio
2
+ class Bank
3
+ Set={
4
+ read: [:read_bank_1 ,:read_bank_2],
5
+ clear: [:clear_bank_1,:clear_bank_2],
6
+ set: [:set_bank_1 ,:set_bank_2],
7
+ }
8
+ def initialize(pi,num)
9
+ @pi=pi
10
+ @num=num
11
+ end
12
+ def read
13
+ IF.send(Set[:read][@num],@pi)
14
+ end
15
+ def clear(bits)
16
+ IF.send(Set[:clear][@num],@pi,bits)
17
+ end
18
+ def set(bits)
19
+ IF.send(Set[:set][@num],@pi,bits)
20
+ end
10
21
  end
11
- def read
12
- IF.send(Set[:read][@num],@pi)
13
- end
14
- def clear(bits)
15
- IF.send(Set[:clear][@num],@pi,bits)
16
- end
17
- def set(bits)
18
- IF.send(Set[:set][@num],@pi,bits)
19
- end
20
- end
22
+ end
data/lib/pigpio/gpio.rb CHANGED
@@ -1,31 +1,32 @@
1
- class Pigpio::GPIO
2
- IF=Pigpio::IF
3
- def initialize(pi,gpio)
4
- @pi=pi #0-15
5
- @gpio=gpio #0-53
6
- end
7
- def gpio
8
- [@pi,@gpio]
9
- end
10
- def mode=(mode)
11
- ret=IF.set_mode(@pi,@gpio,mode)
12
- end
13
- def mode
14
- ret=IF.get_mode(@pi,@gpio)
15
- end
16
- def pud=(pud)
17
- ret=IF.set_pull_up_down(@pi,@gpio,pud)
18
- end
19
- def read
20
- ret=IF.gpio_read(@pi,@gpio)
21
- end
22
- def write(level)
23
- ret=IF.gpio_write(@pi,@gpio,level)
24
- end
25
- def hardware_clock(clkfreq)
26
- ret=IF.hardware_clock(@pi,@gpio,clkfreq)
27
- end
28
- def hardware_PWM(vPWMfreq,vPWMduty)
29
- ret=IF.hardware_PWM(@pi,@gpio,vPWMfreq,vPWMduty)
1
+ class Pigpio
2
+ class GPIO
3
+ def initialize(pi,gpio)
4
+ @pi=pi #0-15
5
+ @gpio=gpio #0-53
6
+ end
7
+ def gpio
8
+ [@pi,@gpio]
9
+ end
10
+ def mode=(mode)
11
+ ret=IF.set_mode(@pi,@gpio,mode)
12
+ end
13
+ def mode
14
+ ret=IF.get_mode(@pi,@gpio)
15
+ end
16
+ def pud=(pud)
17
+ ret=IF.set_pull_up_down(@pi,@gpio,pud)
18
+ end
19
+ def read
20
+ ret=IF.gpio_read(@pi,@gpio)
21
+ end
22
+ def write(level)
23
+ ret=IF.gpio_write(@pi,@gpio,level)
24
+ end
25
+ def hardware_clock(clkfreq)
26
+ ret=IF.hardware_clock(@pi,@gpio,clkfreq)
27
+ end
28
+ def hardware_PWM(vPWMfreq,vPWMduty)
29
+ ret=IF.hardware_PWM(@pi,@gpio,vPWMfreq,vPWMduty)
30
+ end
30
31
  end
31
32
  end
data/lib/pigpio/pwm.rb CHANGED
@@ -1,34 +1,38 @@
1
- class Pigpio::PWM
2
- IF=Pigpio::IF
3
- def initialize(pi,gpio)
4
- @pi=pi
5
- @gpio=gpio
6
- end
7
- def dutycycle=(dutycycle)
8
- ret=IF.set_PWM_dutycycle(@pi,@gpio,dutycycle)
9
- end
10
- def dutycycle
11
- ret=IF.get_PWM_dutycycle(@pi,@gpio)
12
- end
13
- def range=(range)
14
- ret=IF.set_PWM_range(@pi,@gpio,range)
15
- end
16
- def range
17
- ret=IF.get_PWM_range(@pi,@gpio)
18
- end
19
- def real_range
20
- ret=IF.get_PWM_real_range(@pi,@gpio)
21
- end
22
- def frequency=(frequency)
23
- ret=IF.set_PWM_frequency(@pi,@gpio,frequency)
24
- end
25
- def frequency
26
- ret=IF.get_PWM_frequency(@pi,@gpio)
27
- end
28
- def servo_pulsewidth=(pulsewidth)
29
- ret=IF.set_servo_pulsewidth(@pi,@gpio,pulsewidth)
30
- end
31
- def servo_pulsewidth
32
- ret=IF.get_servo_pulsewidth(@pi,@gpio)
1
+ class Pigpio
2
+ class PWM
3
+ def initialize(pi,gpio)
4
+ @pi=pi
5
+ @gpio=gpio
6
+ end
7
+ def start(dutycycle)
8
+ ret=IF.set_PWM_dutycycle(@pi,@gpio,dutycycle)
9
+ end
10
+ def dutycycle=(dutycycle)
11
+ ret=IF.set_PWM_dutycycle(@pi,@gpio,dutycycle)
12
+ end
13
+ def dutycycle
14
+ ret=IF.get_PWM_dutycycle(@pi,@gpio)
15
+ end
16
+ def range=(range)
17
+ ret=IF.set_PWM_range(@pi,@gpio,range)
18
+ end
19
+ def range
20
+ ret=IF.get_PWM_range(@pi,@gpio)
21
+ end
22
+ def real_range
23
+ ret=IF.get_PWM_real_range(@pi,@gpio)
24
+ end
25
+ def frequency=(frequency)
26
+ ret=IF.set_PWM_frequency(@pi,@gpio,frequency)
27
+ end
28
+ def frequency
29
+ ret=IF.get_PWM_frequency(@pi,@gpio)
30
+ end
31
+ def servo_pulsewidth=(pulsewidth)
32
+ ret=IF.set_servo_pulsewidth(@pi,@gpio,pulsewidth)
33
+ end
34
+ def servo_pulsewidth
35
+ ret=IF.get_servo_pulsewidth(@pi,@gpio)
36
+ end
33
37
  end
34
38
  end