wiring_lmk 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/ext/wiringpi/WiringPi/devLib/ds1302.c +254 -0
- data/ext/wiringpi/WiringPi/devLib/ds1302.h +44 -0
- data/ext/wiringpi/WiringPi/devLib/font.h +2577 -0
- data/ext/wiringpi/WiringPi/devLib/gertboard.c +164 -0
- data/ext/wiringpi/WiringPi/devLib/gertboard.h +45 -0
- data/ext/wiringpi/WiringPi/devLib/lcd.c +507 -0
- data/ext/wiringpi/WiringPi/devLib/lcd.h +52 -0
- data/ext/wiringpi/WiringPi/devLib/lcd128x64.c +684 -0
- data/ext/wiringpi/WiringPi/devLib/lcd128x64.h +39 -0
- data/ext/wiringpi/WiringPi/devLib/maxdetect.c +167 -0
- data/ext/wiringpi/WiringPi/devLib/maxdetect.h +40 -0
- data/ext/wiringpi/WiringPi/devLib/piFace.c +112 -0
- data/ext/wiringpi/WiringPi/devLib/piFace.h +32 -0
- data/ext/wiringpi/WiringPi/devLib/piFaceOld.c +178 -0
- data/ext/wiringpi/WiringPi/devLib/piGlow.c +118 -0
- data/ext/wiringpi/WiringPi/devLib/piGlow.h +45 -0
- data/ext/wiringpi/WiringPi/devLib/piNes.c +117 -0
- data/ext/wiringpi/WiringPi/devLib/piNes.h +45 -0
- data/ext/wiringpi/WiringPi/gpio/extensions.c +700 -0
- data/ext/wiringpi/WiringPi/gpio/extensions.h +26 -0
- data/ext/wiringpi/WiringPi/gpio/gpio.c +1280 -0
- data/ext/wiringpi/WiringPi/gpio/pins.c +33 -0
- data/ext/wiringpi/WiringPi/gpio/readall.c +337 -0
- data/ext/wiringpi/WiringPi/wiringPi/drcSerial.c +201 -0
- data/ext/wiringpi/WiringPi/wiringPi/drcSerial.h +33 -0
- data/ext/wiringpi/WiringPi/wiringPi/max31855.c +99 -0
- data/ext/wiringpi/WiringPi/wiringPi/max31855.h +33 -0
- data/ext/wiringpi/WiringPi/wiringPi/max5322.c +84 -0
- data/ext/wiringpi/WiringPi/wiringPi/max5322.h +33 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp23008.c +149 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp23008.h +33 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp23016.c +164 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp23016.h +33 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp23016reg.h +48 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp23017.c +195 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp23017.h +33 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp23s08.c +189 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp23s08.h +33 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp23s17.c +234 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp23s17.h +33 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp23x08.h +73 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp23x0817.h +87 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp3002.c +76 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp3002.h +33 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp3004.c +76 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp3004.h +33 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp3422.c +113 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp3422.h +43 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp4802.c +76 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp4802.h +33 -0
- data/ext/wiringpi/WiringPi/wiringPi/pcf8574.c +126 -0
- data/ext/wiringpi/WiringPi/wiringPi/pcf8574.h +33 -0
- data/ext/wiringpi/WiringPi/wiringPi/pcf8591.c +92 -0
- data/ext/wiringpi/WiringPi/wiringPi/pcf8591.h +33 -0
- data/ext/wiringpi/WiringPi/wiringPi/piHiPri.c +51 -0
- data/ext/wiringpi/WiringPi/wiringPi/piThread.c +63 -0
- data/ext/wiringpi/WiringPi/wiringPi/sn3218.c +75 -0
- data/ext/wiringpi/WiringPi/wiringPi/sn3218.h +33 -0
- data/ext/wiringpi/WiringPi/wiringPi/softPwm.c +168 -0
- data/ext/wiringpi/WiringPi/wiringPi/softPwm.h +35 -0
- data/ext/wiringpi/WiringPi/wiringPi/softServo.c +247 -0
- data/ext/wiringpi/WiringPi/wiringPi/softServo.h +35 -0
- data/ext/wiringpi/WiringPi/wiringPi/softTone.c +150 -0
- data/ext/wiringpi/WiringPi/wiringPi/softTone.h +39 -0
- data/ext/wiringpi/WiringPi/wiringPi/sr595.c +113 -0
- data/ext/wiringpi/WiringPi/wiringPi/sr595.h +34 -0
- data/ext/wiringpi/WiringPi/wiringPi/wiringPi.c +3688 -0
- data/ext/wiringpi/WiringPi/wiringPi/wiringPi.h +229 -0
- data/ext/wiringpi/WiringPi/wiringPi/wiringPiI2C.c +236 -0
- data/ext/wiringpi/WiringPi/wiringPi/wiringPiI2C.h +42 -0
- data/ext/wiringpi/WiringPi/wiringPi/wiringPiSPI.c +121 -0
- data/ext/wiringpi/WiringPi/wiringPi/wiringPiSPI.h +35 -0
- data/ext/wiringpi/WiringPi/wiringPi/wiringSerial.c +253 -0
- data/ext/wiringpi/WiringPi/wiringPi/wiringSerial.h +38 -0
- data/ext/wiringpi/WiringPi/wiringPi/wiringShift.c +83 -0
- data/ext/wiringpi/WiringPi/wiringPi/wiringShift.h +41 -0
- data/ext/wiringpi/extconf.rb +8 -0
- data/ext/wiringpi/wiringpi_wrap.c +4396 -0
- data/lib/wiring_lmk.rb +42 -0
- data/lib/wiring_lmk/event.rb +21 -0
- data/lib/wiring_lmk/gpio.rb +139 -0
- data/lib/wiring_lmk/i2c.rb +26 -0
- data/lib/wiring_lmk/mcp23x17.rb +31 -0
- data/lib/wiring_lmk/serial.rb +49 -0
- data/lib/wiring_lmk/spi.rb +15 -0
- metadata +136 -0
@@ -0,0 +1,63 @@
|
|
1
|
+
/*
|
2
|
+
* piThread.c:
|
3
|
+
* Provide a simplified interface to pthreads
|
4
|
+
*
|
5
|
+
* Copyright (c) 2012 Gordon Henderson
|
6
|
+
***********************************************************************
|
7
|
+
* This file is part of wiringPi:
|
8
|
+
* https://projects.drogon.net/raspberry-pi/wiringpi/
|
9
|
+
*
|
10
|
+
* wiringPi is free software: you can redistribute it and/or modify
|
11
|
+
* it under the terms of the GNU Lesser General Public License as
|
12
|
+
* published by the Free Software Foundation, either version 3 of the
|
13
|
+
* License, or (at your option) any later version.
|
14
|
+
*
|
15
|
+
* wiringPi is distributed in the hope that it will be useful,
|
16
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
17
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
18
|
+
* GNU Lesser General Public License for more details.
|
19
|
+
*
|
20
|
+
* You should have received a copy of the GNU Lesser General Public
|
21
|
+
* License along with wiringPi.
|
22
|
+
* If not, see <http://www.gnu.org/licenses/>.
|
23
|
+
***********************************************************************
|
24
|
+
*/
|
25
|
+
|
26
|
+
#include <pthread.h>
|
27
|
+
#include "wiringPi.h"
|
28
|
+
|
29
|
+
static pthread_mutex_t piMutexes [4] ;
|
30
|
+
|
31
|
+
|
32
|
+
|
33
|
+
/*
|
34
|
+
* piThreadCreate:
|
35
|
+
* Create and start a thread
|
36
|
+
*********************************************************************************
|
37
|
+
*/
|
38
|
+
|
39
|
+
int piThreadCreate (void *(*fn)(void *))
|
40
|
+
{
|
41
|
+
pthread_t myThread ;
|
42
|
+
|
43
|
+
return pthread_create (&myThread, NULL, fn, NULL) ;
|
44
|
+
}
|
45
|
+
|
46
|
+
/*
|
47
|
+
* piLock: piUnlock:
|
48
|
+
* Activate/Deactivate a mutex.
|
49
|
+
* We're keeping things simple here and only tracking 4 mutexes which
|
50
|
+
* is more than enough for out entry-level pthread programming
|
51
|
+
*********************************************************************************
|
52
|
+
*/
|
53
|
+
|
54
|
+
void piLock (int key)
|
55
|
+
{
|
56
|
+
pthread_mutex_lock (&piMutexes [key]) ;
|
57
|
+
}
|
58
|
+
|
59
|
+
void piUnlock (int key)
|
60
|
+
{
|
61
|
+
pthread_mutex_unlock (&piMutexes [key]) ;
|
62
|
+
}
|
63
|
+
|
@@ -0,0 +1,75 @@
|
|
1
|
+
/*
|
2
|
+
* sn3218.c:
|
3
|
+
* Extend wiringPi with the SN3218 I2C LEd Driver
|
4
|
+
* Copyright (c) 2012-2013 Gordon Henderson
|
5
|
+
***********************************************************************
|
6
|
+
* This file is part of wiringPi:
|
7
|
+
* https://projects.drogon.net/raspberry-pi/wiringpi/
|
8
|
+
*
|
9
|
+
* wiringPi is free software: you can redistribute it and/or modify
|
10
|
+
* it under the terms of the GNU Lesser General Public License as
|
11
|
+
* published by the Free Software Foundation, either version 3 of the
|
12
|
+
* License, or (at your option) any later version.
|
13
|
+
*
|
14
|
+
* wiringPi is distributed in the hope that it will be useful,
|
15
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
16
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
17
|
+
* GNU Lesser General Public License for more details.
|
18
|
+
*
|
19
|
+
* You should have received a copy of the GNU Lesser General Public
|
20
|
+
* License along with wiringPi.
|
21
|
+
* If not, see <http://www.gnu.org/licenses/>.
|
22
|
+
***********************************************************************
|
23
|
+
*/
|
24
|
+
|
25
|
+
#include "wiringPi.h"
|
26
|
+
#include "wiringPiI2C.h"
|
27
|
+
|
28
|
+
#include "sn3218.h"
|
29
|
+
|
30
|
+
/*
|
31
|
+
* myAnalogWrite:
|
32
|
+
* Write analog value on the given pin
|
33
|
+
*********************************************************************************
|
34
|
+
*/
|
35
|
+
|
36
|
+
static void myAnalogWrite (struct wiringPiNodeStruct *node, int pin, int value)
|
37
|
+
{
|
38
|
+
int fd = node->fd ;
|
39
|
+
int chan = 0x01 + (pin - node->pinBase) ;
|
40
|
+
|
41
|
+
wiringPiI2CWriteReg8 (fd, chan, value & 0xFF) ; // Value
|
42
|
+
wiringPiI2CWriteReg8 (fd, 0x16, 0x00) ; // Update
|
43
|
+
}
|
44
|
+
|
45
|
+
/*
|
46
|
+
* sn3218Setup:
|
47
|
+
* Create a new wiringPi device node for an sn3218 on the Pi's
|
48
|
+
* SPI interface.
|
49
|
+
*********************************************************************************
|
50
|
+
*/
|
51
|
+
|
52
|
+
int sn3218Setup (const int pinBase)
|
53
|
+
{
|
54
|
+
int fd ;
|
55
|
+
struct wiringPiNodeStruct *node ;
|
56
|
+
|
57
|
+
if ((fd = wiringPiI2CSetup (0x54)) < 0)
|
58
|
+
return fd ;
|
59
|
+
|
60
|
+
// Setup the chip - initialise all 18 LEDs to off
|
61
|
+
|
62
|
+
//wiringPiI2CWriteReg8 (fd, 0x17, 0) ; // Reset
|
63
|
+
wiringPiI2CWriteReg8 (fd, 0x00, 1) ; // Not Shutdown
|
64
|
+
wiringPiI2CWriteReg8 (fd, 0x13, 0x3F) ; // Enable LEDs 0- 5
|
65
|
+
wiringPiI2CWriteReg8 (fd, 0x14, 0x3F) ; // Enable LEDs 6-11
|
66
|
+
wiringPiI2CWriteReg8 (fd, 0x15, 0x3F) ; // Enable LEDs 12-17
|
67
|
+
wiringPiI2CWriteReg8 (fd, 0x16, 0x00) ; // Update
|
68
|
+
|
69
|
+
node = wiringPiNewNode (pinBase, 18) ;
|
70
|
+
|
71
|
+
node->fd = fd ;
|
72
|
+
node->analogWrite = myAnalogWrite ;
|
73
|
+
|
74
|
+
return 0 ;
|
75
|
+
}
|
@@ -0,0 +1,33 @@
|
|
1
|
+
/*
|
2
|
+
* sn3218.c:
|
3
|
+
* Extend wiringPi with the SN3218 I2C LED driver board.
|
4
|
+
* Copyright (c) 2012-2013 Gordon Henderson
|
5
|
+
***********************************************************************
|
6
|
+
* This file is part of wiringPi:
|
7
|
+
* https://projects.drogon.net/raspberry-pi/wiringpi/
|
8
|
+
*
|
9
|
+
* wiringPi is free software: you can redistribute it and/or modify
|
10
|
+
* it under the terms of the GNU Lesser General Public License as
|
11
|
+
* published by the Free Software Foundation, either version 3 of the
|
12
|
+
* License, or (at your option) any later version.
|
13
|
+
*
|
14
|
+
* wiringPi is distributed in the hope that it will be useful,
|
15
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
16
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
17
|
+
* GNU Lesser General Public License for more details.
|
18
|
+
*
|
19
|
+
* You should have received a copy of the GNU Lesser General Public
|
20
|
+
* License along with wiringPi.
|
21
|
+
* If not, see <http://www.gnu.org/licenses/>.
|
22
|
+
***********************************************************************
|
23
|
+
*/
|
24
|
+
|
25
|
+
#ifdef __cplusplus
|
26
|
+
extern "C" {
|
27
|
+
#endif
|
28
|
+
|
29
|
+
extern int sn3218Setup (int pinBase) ;
|
30
|
+
|
31
|
+
#ifdef __cplusplus
|
32
|
+
}
|
33
|
+
#endif
|
@@ -0,0 +1,168 @@
|
|
1
|
+
/*
|
2
|
+
* softPwm.c:
|
3
|
+
* Provide 2 channels of software driven PWM.
|
4
|
+
* Copyright (c) 2012-2014 Gordon Henderson
|
5
|
+
***********************************************************************
|
6
|
+
* This file is part of wiringPi:
|
7
|
+
* https://projects.drogon.net/raspberry-pi/wiringpi/
|
8
|
+
*
|
9
|
+
* wiringPi is free software: you can redistribute it and/or modify
|
10
|
+
* it under the terms of the GNU Lesser General Public License as
|
11
|
+
* published by the Free Software Foundation, either version 3 of the
|
12
|
+
* License, or (at your option) any later version.
|
13
|
+
*
|
14
|
+
* wiringPi is distributed in the hope that it will be useful,
|
15
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
16
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
17
|
+
* GNU Lesser General Public License for more details.
|
18
|
+
*
|
19
|
+
* You should have received a copy of the GNU Lesser General Public
|
20
|
+
* License along with wiringPi.
|
21
|
+
* If not, see <http://www.gnu.org/licenses/>.
|
22
|
+
***********************************************************************
|
23
|
+
*/
|
24
|
+
|
25
|
+
#include <stdio.h>
|
26
|
+
#include <pthread.h>
|
27
|
+
|
28
|
+
#include "wiringPi.h"
|
29
|
+
#include "softPwm.h"
|
30
|
+
|
31
|
+
// MAX_PINS:
|
32
|
+
// This is more than the number of Pi pins because we can actually softPwm
|
33
|
+
// pins that are on GPIO expanders. It's not that efficient and more than 1 or
|
34
|
+
// 2 pins on e.g. (SPI) mcp23s17 won't really be that effective, however...
|
35
|
+
|
36
|
+
#define MAX_PINS 1024
|
37
|
+
|
38
|
+
// The PWM Frequency is derived from the "pulse time" below. Essentially,
|
39
|
+
// the frequency is a function of the range and this pulse time.
|
40
|
+
// The total period will be range * pulse time in μS, so a pulse time
|
41
|
+
// of 100 and a range of 100 gives a period of 100 * 100 = 10,000 μS
|
42
|
+
// which is a frequency of 100Hz.
|
43
|
+
//
|
44
|
+
// It's possible to get a higher frequency by lowering the pulse time,
|
45
|
+
// however CPU uage will skyrocket as wiringPi uses a hard-loop to time
|
46
|
+
// periods under 100μS - this is because the Linux timer calls are just
|
47
|
+
// accurate at all, and have an overhead.
|
48
|
+
//
|
49
|
+
// Another way to increase the frequency is to reduce the range - however
|
50
|
+
// that reduces the overall output accuracy...
|
51
|
+
|
52
|
+
#define PULSE_TIME 100
|
53
|
+
|
54
|
+
static volatile int marks [MAX_PINS] ;
|
55
|
+
static volatile int range [MAX_PINS] ;
|
56
|
+
static volatile pthread_t threads [MAX_PINS] ;
|
57
|
+
static volatile int newPin = -1 ;
|
58
|
+
|
59
|
+
|
60
|
+
/*
|
61
|
+
* softPwmThread:
|
62
|
+
* Thread to do the actual PWM output
|
63
|
+
*********************************************************************************
|
64
|
+
*/
|
65
|
+
|
66
|
+
static PI_THREAD (softPwmThread)
|
67
|
+
{
|
68
|
+
int pin, mark, space ;
|
69
|
+
struct sched_param param ;
|
70
|
+
|
71
|
+
param.sched_priority = sched_get_priority_max (SCHED_RR) ;
|
72
|
+
pthread_setschedparam (pthread_self (), SCHED_RR, ¶m) ;
|
73
|
+
|
74
|
+
pin = newPin ;
|
75
|
+
newPin = -1 ;
|
76
|
+
|
77
|
+
piHiPri (90) ;
|
78
|
+
|
79
|
+
for (;;)
|
80
|
+
{
|
81
|
+
mark = marks [pin] ;
|
82
|
+
space = range [pin] - mark ;
|
83
|
+
|
84
|
+
if (mark != 0)
|
85
|
+
digitalWrite (pin, HIGH) ;
|
86
|
+
delayMicroseconds (mark * 100) ;
|
87
|
+
delay(mark * 10);
|
88
|
+
|
89
|
+
if (space != 0)
|
90
|
+
digitalWrite (pin, LOW) ;
|
91
|
+
delayMicroseconds (space * 100) ;
|
92
|
+
delay(mark * 10);
|
93
|
+
}
|
94
|
+
|
95
|
+
return NULL ;
|
96
|
+
}
|
97
|
+
|
98
|
+
|
99
|
+
/*
|
100
|
+
* softPwmWrite:
|
101
|
+
* Write a PWM value to the given pin
|
102
|
+
*********************************************************************************
|
103
|
+
*/
|
104
|
+
|
105
|
+
void softPwmWrite (int pin, int value)
|
106
|
+
{
|
107
|
+
pin &= (MAX_PINS - 1) ;
|
108
|
+
|
109
|
+
/**/ if (value < 0)
|
110
|
+
value = 0 ;
|
111
|
+
else if (value > range [pin])
|
112
|
+
value = range [pin] ;
|
113
|
+
|
114
|
+
marks [pin] = value ;
|
115
|
+
}
|
116
|
+
|
117
|
+
|
118
|
+
/*
|
119
|
+
* softPwmCreate:
|
120
|
+
* Create a new softPWM thread.
|
121
|
+
*********************************************************************************
|
122
|
+
*/
|
123
|
+
|
124
|
+
int softPwmCreate (int pin, int initialValue, int pwmRange)
|
125
|
+
{
|
126
|
+
int res ;
|
127
|
+
pthread_t myThread ;
|
128
|
+
|
129
|
+
if (range [pin] != 0) // Already running on this pin
|
130
|
+
return -1 ;
|
131
|
+
|
132
|
+
if (range <= 0)
|
133
|
+
return -1 ;
|
134
|
+
|
135
|
+
pinMode (pin, OUTPUT) ;
|
136
|
+
digitalWrite (pin, LOW) ;
|
137
|
+
|
138
|
+
marks [pin] = initialValue ;
|
139
|
+
range [pin] = pwmRange ;
|
140
|
+
|
141
|
+
newPin = pin ;
|
142
|
+
res = pthread_create (&myThread, NULL, softPwmThread, NULL) ;
|
143
|
+
|
144
|
+
while (newPin != -1)
|
145
|
+
delay (1) ;
|
146
|
+
|
147
|
+
threads [pin] = myThread ;
|
148
|
+
|
149
|
+
return res ;
|
150
|
+
}
|
151
|
+
|
152
|
+
|
153
|
+
/*
|
154
|
+
* softPwmStop:
|
155
|
+
* Stop an existing softPWM thread
|
156
|
+
*********************************************************************************
|
157
|
+
*/
|
158
|
+
|
159
|
+
void softPwmStop (int pin)
|
160
|
+
{
|
161
|
+
if (range [pin] != 0)
|
162
|
+
{
|
163
|
+
pthread_cancel (threads [pin]) ;
|
164
|
+
pthread_join (threads [pin], NULL) ;
|
165
|
+
range [pin] = 0 ;
|
166
|
+
digitalWrite (pin, LOW) ;
|
167
|
+
}
|
168
|
+
}
|
@@ -0,0 +1,35 @@
|
|
1
|
+
/*
|
2
|
+
* softPwm.h:
|
3
|
+
* Provide 2 channels of software driven PWM.
|
4
|
+
* Copyright (c) 2012 Gordon Henderson
|
5
|
+
***********************************************************************
|
6
|
+
* This file is part of wiringPi:
|
7
|
+
* https://projects.drogon.net/raspberry-pi/wiringpi/
|
8
|
+
*
|
9
|
+
* wiringPi is free software: you can redistribute it and/or modify
|
10
|
+
* it under the terms of the GNU Lesser General Public License as
|
11
|
+
* published by the Free Software Foundation, either version 3 of the
|
12
|
+
* License, or (at your option) any later version.
|
13
|
+
*
|
14
|
+
* wiringPi is distributed in the hope that it will be useful,
|
15
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
16
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
17
|
+
* GNU Lesser General Public License for more details.
|
18
|
+
*
|
19
|
+
* You should have received a copy of the GNU Lesser General Public
|
20
|
+
* License along with wiringPi.
|
21
|
+
* If not, see <http://www.gnu.org/licenses/>.
|
22
|
+
***********************************************************************
|
23
|
+
*/
|
24
|
+
|
25
|
+
#ifdef __cplusplus
|
26
|
+
extern "C" {
|
27
|
+
#endif
|
28
|
+
|
29
|
+
extern int softPwmCreate (int pin, int value, int range) ;
|
30
|
+
extern void softPwmWrite (int pin, int value) ;
|
31
|
+
extern void softPwmStop (int pin) ;
|
32
|
+
|
33
|
+
#ifdef __cplusplus
|
34
|
+
}
|
35
|
+
#endif
|
@@ -0,0 +1,247 @@
|
|
1
|
+
/*
|
2
|
+
* softServo.c:
|
3
|
+
* Provide N channels of software driven PWM suitable for RC
|
4
|
+
* servo motors.
|
5
|
+
* Copyright (c) 2012 Gordon Henderson
|
6
|
+
***********************************************************************
|
7
|
+
* This file is part of wiringPi:
|
8
|
+
* https://projects.drogon.net/raspberry-pi/wiringpi/
|
9
|
+
*
|
10
|
+
* wiringPi is free software: you can redistribute it and/or modify
|
11
|
+
* it under the terms of the GNU Lesser General Public License as
|
12
|
+
* published by the Free Software Foundation, either version 3 of the
|
13
|
+
* License, or (at your option) any later version.
|
14
|
+
*
|
15
|
+
* wiringPi is distributed in the hope that it will be useful,
|
16
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
17
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
18
|
+
* GNU Lesser General Public License for more details.
|
19
|
+
*
|
20
|
+
* You should have received a copy of the GNU Lesser General Public
|
21
|
+
* License along with wiringPi.
|
22
|
+
* If not, see <http://www.gnu.org/licenses/>.
|
23
|
+
***********************************************************************
|
24
|
+
*/
|
25
|
+
|
26
|
+
//#include <stdio.h>
|
27
|
+
#include <string.h>
|
28
|
+
#include <time.h>
|
29
|
+
#include <sys/time.h>
|
30
|
+
#include <pthread.h>
|
31
|
+
|
32
|
+
#include "wiringPi.h"
|
33
|
+
#include "softServo.h"
|
34
|
+
|
35
|
+
// RC Servo motors are a bit of an oddity - designed in the days when
|
36
|
+
// radio control was experimental and people were tryin to make
|
37
|
+
// things as simple as possible as it was all very expensive...
|
38
|
+
//
|
39
|
+
// So... To drive an RC Servo motor, you need to send it a modified PWM
|
40
|
+
// signal - it needs anything from 1ms to 2ms - with 1ms meaning
|
41
|
+
// to move the server fully left, and 2ms meaning to move it fully
|
42
|
+
// right. Then you need a long gap before sending the next pulse.
|
43
|
+
// The reason for this is that you send a multiplexed stream of these
|
44
|
+
// pulses up the radio signal into the reciever which de-multiplexes
|
45
|
+
// them into the signals for each individual servo. Typically there
|
46
|
+
// might be 8 channels, so you need at least 8 "slots" of 2mS pulses
|
47
|
+
// meaning the entire frame must fit into a 16mS slot - which would
|
48
|
+
// then be repeated...
|
49
|
+
//
|
50
|
+
// In practice we have a total slot width of about 20mS - so we're sending 50
|
51
|
+
// updates per second to each servo.
|
52
|
+
//
|
53
|
+
// In this code, we don't need to be too fussy about the gap as we're not doing
|
54
|
+
// the multipexing, but it does need to be at least 10mS, and preferably 16
|
55
|
+
// from what I've been able to determine.
|
56
|
+
|
57
|
+
// WARNING:
|
58
|
+
// This code is really experimental. It was written in response to some people
|
59
|
+
// asking for a servo driver, however while it works, there is too much
|
60
|
+
// jitter to successfully drive a small servo - I have tried it with a micro
|
61
|
+
// servo and it worked, but the servo ran hot due to the jitter in the signal
|
62
|
+
// being sent to it.
|
63
|
+
//
|
64
|
+
// If you want servo control for the Pi, then use the servoblaster kernel
|
65
|
+
// module.
|
66
|
+
|
67
|
+
#define MAX_SERVOS 8
|
68
|
+
|
69
|
+
static int pinMap [MAX_SERVOS] ; // Keep track of our pins
|
70
|
+
static int pulseWidth [MAX_SERVOS] ; // microseconds
|
71
|
+
|
72
|
+
|
73
|
+
/*
|
74
|
+
* softServoThread:
|
75
|
+
* Thread to do the actual Servo PWM output
|
76
|
+
*********************************************************************************
|
77
|
+
*/
|
78
|
+
|
79
|
+
static PI_THREAD (softServoThread)
|
80
|
+
{
|
81
|
+
register int i, j, k, m, tmp ;
|
82
|
+
int lastDelay, pin, servo ;
|
83
|
+
|
84
|
+
int myDelays [MAX_SERVOS] ;
|
85
|
+
int myPins [MAX_SERVOS] ;
|
86
|
+
|
87
|
+
struct timeval tNow, tStart, tPeriod, tGap, tTotal ;
|
88
|
+
struct timespec tNs ;
|
89
|
+
|
90
|
+
tTotal.tv_sec = 0 ;
|
91
|
+
tTotal.tv_usec = 8000 ;
|
92
|
+
|
93
|
+
piHiPri (50) ;
|
94
|
+
|
95
|
+
for (;;)
|
96
|
+
{
|
97
|
+
gettimeofday (&tStart, NULL) ;
|
98
|
+
|
99
|
+
memcpy (myDelays, pulseWidth, sizeof (myDelays)) ;
|
100
|
+
memcpy (myPins, pinMap, sizeof (myPins)) ;
|
101
|
+
|
102
|
+
// Sort the delays (& pins), shortest first
|
103
|
+
|
104
|
+
for (m = MAX_SERVOS / 2 ; m > 0 ; m /= 2 )
|
105
|
+
for (j = m ; j < MAX_SERVOS ; ++j)
|
106
|
+
for (i = j - m ; i >= 0 ; i -= m)
|
107
|
+
{
|
108
|
+
k = i + m ;
|
109
|
+
if (myDelays [k] >= myDelays [i])
|
110
|
+
break ;
|
111
|
+
else // Swap
|
112
|
+
{
|
113
|
+
tmp = myDelays [i] ;
|
114
|
+
myDelays [i] = myDelays [k] ;
|
115
|
+
myDelays [k] = tmp ;
|
116
|
+
tmp = myPins [i] ;
|
117
|
+
myPins [i] = myPins [k] ;
|
118
|
+
myPins [k] = tmp ;
|
119
|
+
}
|
120
|
+
}
|
121
|
+
|
122
|
+
// All on
|
123
|
+
|
124
|
+
lastDelay = 0 ;
|
125
|
+
for (servo = 0 ; servo < MAX_SERVOS ; ++servo)
|
126
|
+
{
|
127
|
+
if ((pin = myPins [servo]) == -1)
|
128
|
+
continue ;
|
129
|
+
|
130
|
+
digitalWrite (pin, HIGH) ;
|
131
|
+
myDelays [servo] = myDelays [servo] - lastDelay ;
|
132
|
+
lastDelay += myDelays [servo] ;
|
133
|
+
}
|
134
|
+
|
135
|
+
// Now loop, turning them all off as required
|
136
|
+
|
137
|
+
for (servo = 0 ; servo < MAX_SERVOS ; ++servo)
|
138
|
+
{
|
139
|
+
if ((pin = myPins [servo]) == -1)
|
140
|
+
continue ;
|
141
|
+
|
142
|
+
delayMicroseconds (myDelays [servo]) ;
|
143
|
+
digitalWrite (pin, LOW) ;
|
144
|
+
}
|
145
|
+
|
146
|
+
// Wait until the end of an 8mS time-slot
|
147
|
+
|
148
|
+
gettimeofday (&tNow, NULL) ;
|
149
|
+
timersub (&tNow, &tStart, &tPeriod) ;
|
150
|
+
timersub (&tTotal, &tPeriod, &tGap) ;
|
151
|
+
tNs.tv_sec = tGap.tv_sec ;
|
152
|
+
tNs.tv_nsec = tGap.tv_usec * 1000 ;
|
153
|
+
nanosleep (&tNs, NULL) ;
|
154
|
+
}
|
155
|
+
|
156
|
+
return NULL ;
|
157
|
+
}
|
158
|
+
|
159
|
+
|
160
|
+
/*
|
161
|
+
* softServoWrite:
|
162
|
+
* Write a Servo value to the given pin
|
163
|
+
*********************************************************************************
|
164
|
+
*/
|
165
|
+
|
166
|
+
void softServoWrite (int servoPin, int value)
|
167
|
+
{
|
168
|
+
int servo ;
|
169
|
+
|
170
|
+
servoPin &= 63 ;
|
171
|
+
|
172
|
+
/**/ if (value < -250)
|
173
|
+
value = -250 ;
|
174
|
+
else if (value > 1250)
|
175
|
+
value = 1250 ;
|
176
|
+
|
177
|
+
for (servo = 0 ; servo < MAX_SERVOS ; ++servo)
|
178
|
+
if (pinMap [servo] == servoPin)
|
179
|
+
pulseWidth [servo] = value + 1000 ; // uS
|
180
|
+
}
|
181
|
+
|
182
|
+
|
183
|
+
/*
|
184
|
+
* softServoSetup:
|
185
|
+
* Setup the software servo system
|
186
|
+
*********************************************************************************
|
187
|
+
*/
|
188
|
+
|
189
|
+
int softServoSetup (int p0, int p1, int p2, int p3, int p4, int p5, int p6, int p7)
|
190
|
+
{
|
191
|
+
int servo ;
|
192
|
+
|
193
|
+
if (p0 != -1)
|
194
|
+
{
|
195
|
+
pinMode (p0, OUTPUT) ;
|
196
|
+
digitalWrite (p0, LOW) ;
|
197
|
+
}
|
198
|
+
if (p1 != -1)
|
199
|
+
{
|
200
|
+
pinMode (p1, OUTPUT) ;
|
201
|
+
digitalWrite (p1, LOW) ;
|
202
|
+
}
|
203
|
+
if (p2 != -1)
|
204
|
+
{
|
205
|
+
pinMode (p2, OUTPUT) ;
|
206
|
+
digitalWrite (p2, LOW) ;
|
207
|
+
}
|
208
|
+
if (p3 != -1)
|
209
|
+
{
|
210
|
+
pinMode (p3, OUTPUT) ;
|
211
|
+
digitalWrite (p3, LOW) ;
|
212
|
+
}
|
213
|
+
if (p4 != -1)
|
214
|
+
{
|
215
|
+
pinMode (p4, OUTPUT) ;
|
216
|
+
digitalWrite (p4, LOW) ;
|
217
|
+
}
|
218
|
+
if (p5 != -1)
|
219
|
+
{
|
220
|
+
pinMode (p5, OUTPUT) ;
|
221
|
+
digitalWrite (p5, LOW) ;
|
222
|
+
}
|
223
|
+
if (p6 != -1)
|
224
|
+
{
|
225
|
+
pinMode (p6, OUTPUT) ;
|
226
|
+
digitalWrite (p6, LOW) ;
|
227
|
+
}
|
228
|
+
if (p7 != -1)
|
229
|
+
{
|
230
|
+
pinMode (p7, OUTPUT) ;
|
231
|
+
digitalWrite (p7, LOW) ;
|
232
|
+
}
|
233
|
+
|
234
|
+
pinMap [0] = p0 ;
|
235
|
+
pinMap [1] = p1 ;
|
236
|
+
pinMap [2] = p2 ;
|
237
|
+
pinMap [3] = p3 ;
|
238
|
+
pinMap [4] = p4 ;
|
239
|
+
pinMap [5] = p5 ;
|
240
|
+
pinMap [6] = p6 ;
|
241
|
+
pinMap [7] = p7 ;
|
242
|
+
|
243
|
+
for (servo = 0 ; servo < MAX_SERVOS ; ++servo)
|
244
|
+
pulseWidth [servo] = 1500 ; // Mid point
|
245
|
+
|
246
|
+
return piThreadCreate (softServoThread) ;
|
247
|
+
}
|