rpi-io 1.2.4 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,192 @@
1
+ #!/bin/bash
2
+ # -------------------------------------------------------------------
3
+ # RPI-IO: Script to check environment for libgpiod
4
+ # source: claude.ai/chat/f3139163-e976-47a4-8e46-01fee65686f2
5
+ # Check: OS, Node.js, npm, node-gyp, gcc, make, Python, libgpiod
6
+ # gpio permissions, pthread
7
+ # -------------------------------------------------------------------
8
+ echo "=== Check environment for libgpiod ==="
9
+ echo ""
10
+
11
+ RED="\033[0;31m"
12
+ GREEN='\033[0;32m'
13
+ YELLOW='\033[1;33m'
14
+ NC='\033[0m' # No Color
15
+
16
+ check_ok() {
17
+ echo -e "${GREEN}✓${NC} $1"
18
+ }
19
+
20
+ check_fail() {
21
+ echo -e "${RED}✗${NC} $1"
22
+ }
23
+
24
+ check_warn() {
25
+ echo -e "${YELLOW}⚠${NC} $1"
26
+ }
27
+
28
+ # Check OS
29
+ echo "1. Operating system"
30
+ if [ -f /etc/os-release ]; then
31
+ . /etc/os-release
32
+ check_ok "OS: $PRETTY_NAME"
33
+ else
34
+ check_warn "Impossible to detect OS"
35
+ fi
36
+ echo ""
37
+
38
+ # Check Node.js
39
+ echo "2. Node.js"
40
+ if command -v node &> /dev/null; then
41
+ NODE_VERSION=$(node --version)
42
+ check_ok "Node.js installed: $NODE_VERSION"
43
+ else
44
+ check_fail "Node.js is not installed"
45
+ echo " Install it with: sudo apt-get install nodejs"
46
+ fi
47
+ echo ""
48
+
49
+ # Check npm
50
+ echo "3. npm"
51
+ if command -v npm &> /dev/null; then
52
+ NPM_VERSION=$(npm --version)
53
+ check_ok "npm installed: v$NPM_VERSION"
54
+ else
55
+ check_fail "npm is not installed"
56
+ fi
57
+ echo ""
58
+
59
+ # Check node-gyp
60
+ echo "4. node-gyp"
61
+ if npm list -g node-gyp &> /dev/null; then
62
+ check_ok "node-gyp is installed globally"
63
+ elif npm list node-gyp &> /dev/null; then
64
+ check_ok "node-gyp is installed locally"
65
+ else
66
+ check_warn "node-gyp is not detected (it will be installed by npm install)"
67
+ fi
68
+ echo ""
69
+
70
+ # Check gcc
71
+ echo "5. Compile tools"
72
+ if command -v gcc &> /dev/null; then
73
+ GCC_VERSION=$(gcc --version | head -n1)
74
+ check_ok "gcc is installed: $GCC_VERSION"
75
+ else
76
+ check_fail "gcc is not installed"
77
+ echo " Install it with: sudo apt-get install build-essential"
78
+ fi
79
+
80
+ if command -v make &> /dev/null; then
81
+ check_ok "make is installed"
82
+ else
83
+ check_fail "make is not installed"
84
+ fi
85
+ echo ""
86
+
87
+ # Check Python (required by node-gyp)
88
+ echo "6. Python (required by node-gyp)"
89
+ if command -v python3 &> /dev/null; then
90
+ PYTHON_VERSION=$(python3 --version)
91
+ check_ok "$PYTHON_VERSION"
92
+ else
93
+ check_fail "Python 3 is not installed"
94
+ fi
95
+ echo ""
96
+
97
+ # Check libgpiod
98
+ echo "7. libgpiod"
99
+ if command -v gpioinfo &> /dev/null; then
100
+ GPIOD_VERSION=$(gpioinfo --version 2>&1 | head -n1)
101
+ check_ok "libgpiod is installed: $GPIOD_VERSION"
102
+ else
103
+ check_fail "libgpiod is not installed"
104
+ echo " Install with: sudo apt-get install gpiod"
105
+ fi
106
+
107
+ if [ -f /usr/include/gpiod.h ]; then
108
+ check_ok "Headers libgpiod trouvés: /usr/include/gpiod.h"
109
+
110
+ # Détect header version
111
+ if grep -q "GPIOD_API_VERSION" /usr/include/gpiod.h; then
112
+ check_ok "libgpiod v2.x detected (GPIOD_API_VERSION found)"
113
+ else
114
+ check_ok "libgpiod v1.x detected"
115
+ fi
116
+ else
117
+ check_fail "libgpiod headers not found"
118
+ echo " Install it with: sudo apt-get install libgpiod-dev"
119
+ fi
120
+
121
+ if [ -f /usr/lib/aarch64-linux-gnu/libgpiod.so ] || [ -f /usr/lib/arm-linux-gnueabihf/libgpiod.so ] || [ -f /usr/lib/x86_64-linux-gnu/libgpiod.so ]; then
122
+ check_ok "libgpiod lib found"
123
+ else
124
+ check_fail "libgpiod lib not found"
125
+ fi
126
+ echo ""
127
+
128
+ # Check GPIO permissions
129
+ echo "8. Permissions GPIO"
130
+ if [ -e /dev/gpiochip0 ]; then
131
+ check_ok "/dev/gpiochip0 found"
132
+
133
+ if groups $USER | grep -q gpio; then
134
+ check_ok "User $USER is in the gpio group"
135
+ else
136
+ check_warn "User $USER is not in the gpio group"
137
+ echo " Add him/her with: sudo usermod -a -G gpio $USER"
138
+ echo " Then log back in."
139
+ fi
140
+
141
+ ls -l /dev/gpiochip0
142
+ else
143
+ check_warn "/dev/gpiochip0 is not found (==> not a Raspberry Pi)"
144
+ fi
145
+ echo ""
146
+
147
+ # Check pthread
148
+ echo "9. pthread"
149
+ if [ -f /usr/include/pthread.h ]; then
150
+ check_ok "pthread.h found"
151
+ else
152
+ check_warn "pthread.h not found ⚠️"
153
+ fi
154
+ echo ""
155
+
156
+ # Summary
157
+ echo "=== Summary ==="
158
+ echo ""
159
+
160
+ MISSING=0
161
+
162
+ if ! command -v node &> /dev/null; then
163
+ echo "➤ Install Node.js:"
164
+ echo " sudo apt-get install nodejs npm"
165
+ MISSING=1
166
+ fi
167
+
168
+ if ! command -v gcc &> /dev/null; then
169
+ echo "➤ Install compilation tools:"
170
+ echo " sudo apt-get install build-essential python3"
171
+ MISSING=1
172
+ fi
173
+
174
+ if ! [ -f /usr/include/gpiod.h ]; then
175
+ echo "➤ Install libgpiod and related headers:"
176
+ echo " sudo apt-get install libgpiod-dev gpiod"
177
+ MISSING=1
178
+ fi
179
+
180
+ if [ $MISSING -eq 0 ]; then
181
+ echo -e "${GREEN}✓ All the prerequisites seem to be in place!${NC}"
182
+ echo ""
183
+ echo "Now you can compile with:"
184
+ echo " npm install"
185
+ else
186
+ echo -e "${YELLOW}⚠️ Some prerequisites are missing (see above)${NC}"
187
+ fi
188
+
189
+ echo ""
190
+ echo "To force recompilation:"
191
+ echo " npm run clean"
192
+ echo " npm run build"
@@ -0,0 +1,21 @@
1
+ #!/bin/bash
2
+ # -------------------------------------------------------------------
3
+ # RPI-IO: To detect the libgpiod version
4
+ # -------------------------------------------------------------------
5
+
6
+ VERSION=$(pkg-config --modversion libgpiod 2>/dev/null)
7
+
8
+ if [ -z "$VERSION" ]; then
9
+ echo "Error: Cannot detect libgpiod version" >&2
10
+ exit 1
11
+ fi
12
+
13
+ MAJOR=$(echo $VERSION | cut -d. -f1)
14
+
15
+ echo "Detected libgpiod version: $VERSION (major: $MAJOR)" >&2
16
+
17
+ if [ "$MAJOR" -ge 2 ]; then
18
+ echo "LIBGPIOD_V2"
19
+ else
20
+ echo "LIBGPIOD_V1"
21
+ fi
@@ -0,0 +1,44 @@
1
+ // -------------------------------------------------------------------
2
+ // TEST - Benchmark pwm duty update x1,000,000
3
+ // -------------------------------------------------------------------
4
+ import {RIO, traceCfg, log, lineNumber, ctrlC} from "../esm/main.mjs"
5
+ (async () => {
6
+ traceCfg(2)
7
+ const line = lineNumber(2)
8
+ if (line < 0) return
9
+
10
+ // Init pwm line and set duty = 0%
11
+ const led = new RIO(line, "pwm", {
12
+ period: 1000, // 1,000,000 ns ~ 1 KHz
13
+ dutyMin: 0,
14
+ dutyMax: 1000
15
+ })
16
+
17
+ ctrlC(() => {
18
+ led.close()
19
+ })
20
+
21
+ // pwm update loop x1,000,000
22
+ let len = 1000000
23
+ log("Benchmark pwm update x1,000,000")
24
+ const start = new Date()
25
+ while (len--) {
26
+ led.pwmDuty(50)
27
+ }
28
+ const stop = new Date()
29
+ log("Elapse time:", stop - start, "ms")
30
+ led.close()
31
+ })()
32
+
33
+
34
+
35
+
36
+
37
+
38
+
39
+
40
+
41
+
42
+ // -------------------------------------------------------------------
43
+ // EoF
44
+ // -------------------------------------------------------------------
@@ -0,0 +1,37 @@
1
+ // -------------------------------------------------------------------
2
+ // TEST - Benchmark read x1,000,000
3
+ // -------------------------------------------------------------------
4
+ import {RIO, traceCfg, log, lineNumber} from "../esm/main.mjs"
5
+ (async () => {
6
+ traceCfg(2)
7
+ const line = lineNumber(2)
8
+ if (line < 0) return
9
+
10
+ // Init input line
11
+ const btn = new RIO(line, "input", {bias: "pull-down"})
12
+ log("button:", btn)
13
+
14
+ // read loop x1,000,000
15
+ let len = 1000000
16
+ log("Benchmark read x1,000,000")
17
+ const start = new Date()
18
+ while (len--) {
19
+ btn.read()
20
+ }
21
+ const stop = new Date()
22
+ btn.close();
23
+ log("Elapse time:", stop - start, "ms")
24
+ })()
25
+
26
+
27
+
28
+
29
+
30
+
31
+
32
+
33
+
34
+
35
+ // -------------------------------------------------------------------
36
+ // EoF
37
+ // -------------------------------------------------------------------
@@ -0,0 +1,38 @@
1
+ // -------------------------------------------------------------------
2
+ // TEST - Benchmark write x1,000,000
3
+ // -------------------------------------------------------------------
4
+ import {RIO, traceCfg, log, lineNumber} from "../esm/main.mjs"
5
+ (async () => {
6
+ traceCfg(2)
7
+ const line = lineNumber(2)
8
+ if (line < 0) return
9
+
10
+ // Init output line and ctrl+c to close it
11
+ const led = new RIO(line, "output", {value: 0})
12
+ log("led:", led)
13
+
14
+ // write loop x1,000,000
15
+ let len = 500000
16
+ log("Benchmark write x1,000,000")
17
+ const start = new Date()
18
+ while (len--) {
19
+ led.write(1)
20
+ led.write(0)
21
+ }
22
+ const stop = new Date()
23
+ led.close();
24
+ log("Elapse time:", stop - start, "ms")
25
+ })()
26
+
27
+
28
+
29
+
30
+
31
+
32
+
33
+
34
+
35
+
36
+ // -------------------------------------------------------------------
37
+ // EoF
38
+ // -------------------------------------------------------------------
@@ -0,0 +1,27 @@
1
+ // -------------------------------------------------------------------
2
+ // TEST - closeAll
3
+ // -------------------------------------------------------------------
4
+ import {RIO, traceCfg, log, sleep, ctrlC, lineNumber} from "../esm/main.mjs"
5
+
6
+ (async () => {
7
+ traceCfg(2)
8
+
9
+ const line1 = lineNumber(2)
10
+ if (line1 < 0) return
11
+
12
+ const line2 = lineNumber(3)
13
+ if (line2 < 0) return
14
+
15
+ const led = new RIO(line1, "output", {value: 0})
16
+ const btn = new RIO(line2, "input")
17
+ log("led:", led)
18
+ log("btn:", btn)
19
+
20
+ await sleep(1000)
21
+ RIO.closeAll()
22
+ })()
23
+
24
+
25
+ // -------------------------------------------------------------------
26
+ // EoF
27
+ // -------------------------------------------------------------------
@@ -0,0 +1,29 @@
1
+ // -------------------------------------------------------------------
2
+ // TEST - Duplicate instance
3
+ // -------------------------------------------------------------------
4
+ import {RIO, traceCfg, log, sleep, ctrlC, lineNumber} from "../esm/main.mjs"
5
+
6
+ (async () => {
7
+ traceCfg(2)
8
+
9
+ const line = lineNumber(2)
10
+ if (line < 0) return
11
+
12
+
13
+ let led = new RIO(line, "output", {value: 0})
14
+ led.close()
15
+
16
+ // It works
17
+ led = new RIO(line, "output", {value: 0})
18
+ log("lead again:", led)
19
+
20
+ // It doesn't work!
21
+ log("now an error 🤓")
22
+ const ooops = new RIO(line, "output", {value: 0})
23
+
24
+ })()
25
+
26
+
27
+ // -------------------------------------------------------------------
28
+ // EoF
29
+ // -------------------------------------------------------------------
@@ -0,0 +1,16 @@
1
+ // -------------------------------------------------------------------
2
+ // TEST - Line configuration
3
+ // -------------------------------------------------------------------
4
+ import {traceCfg, log, lineNumber, lineConfig} from "../esm/main.mjs"
5
+
6
+ (async () => {
7
+ traceCfg(2)
8
+ const line = lineNumber(2)
9
+ if (line < 0) return
10
+ log("line", line, "-->", lineConfig(line))
11
+ })()
12
+
13
+
14
+ // -------------------------------------------------------------------
15
+ // EoF
16
+ // -------------------------------------------------------------------
@@ -0,0 +1,36 @@
1
+ // -------------------------------------------------------------------
2
+ // TEST - PWM for led
3
+ // -------------------------------------------------------------------
4
+ import {RIO, traceCfg, log, sleep, ctrlC, lineNumber} from "../esm/main.mjs"
5
+
6
+ (async () => {
7
+ traceCfg(2)
8
+ const line = lineNumber(2)
9
+ if (line < 0) return
10
+
11
+ // Init pwm line and set duty = 0%
12
+ const led = new RIO(line, "pwm", {
13
+ exportTime: 50,// delay for export on init
14
+ period: 1000, // 1,000,000 ns ~ 1 KHz
15
+ dutyMin: 0,
16
+ dutyMax: 1000
17
+ })
18
+ log("led:", led)
19
+ ctrlC(() => {
20
+ led.close()
21
+ })
22
+
23
+ for (let i = 1; i < 101; i++) {
24
+ led.pwmDuty(i)
25
+ await sleep(30, false)
26
+ }
27
+ await sleep(2000)
28
+ led.pwmDuty(0)
29
+ led.close()
30
+ log("led closed")
31
+ })()
32
+
33
+
34
+ // -------------------------------------------------------------------
35
+ // EoF
36
+ // -------------------------------------------------------------------
@@ -0,0 +1,40 @@
1
+ // -------------------------------------------------------------------
2
+ // TEST - PWM for servo-motor SG90
3
+ // Info: https://wiki.openelab.io/motors/servo-motor-sg90
4
+ // -------------------------------------------------------------------
5
+ import {RIO, traceCfg, log, sleep, ctrlC, lineNumber} from "../esm/main.mjs"
6
+
7
+ (async () => {
8
+ traceCfg(2)
9
+ const line = lineNumber(2)
10
+ if (line < 0) return
11
+
12
+ // Init pwm line and set duty = 0%
13
+ const servo = new RIO(line, "pwm", {
14
+ exportTime: 100,// delay for export on init
15
+ period: 20000, // 20,000,000 ns ~ 50 Hz
16
+ dutyMin: 500, // 500,000 ns ~ 0.5 ms
17
+ dutyMax: 2500 // 2,500,000 ns ~ 2.5 ms
18
+ })
19
+ ctrlC(() => {
20
+ servo.close()
21
+ })
22
+ log("servo initialized --> duty = 0%")
23
+ await sleep(2000)
24
+ servo.pwmDuty(50)
25
+ log("servo duty = 50%") // ~ 0.5 + (0.5 * (2.5 ms - 0.5 ms)) = 1.5 ms
26
+ await sleep(2000)
27
+ servo.pwmDuty(100)
28
+ log("servo duty = 100%") // ~ 0.5 + (1.0 * (2.5 ms - 0.5 ms)) = 2.5 ms
29
+ await sleep(2000)
30
+ servo.pwmDuty(0)
31
+ log("servo duty = 0%") // ~ 0.5 + (0.0 * (2.5 ms - 0.5 ms)) = 0.5 ms
32
+ await sleep(2000)
33
+ servo.close()
34
+ log("servo closed")
35
+ })()
36
+
37
+
38
+ // -------------------------------------------------------------------
39
+ // EoF
40
+ // -------------------------------------------------------------------
package/test/read.js ADDED
@@ -0,0 +1,30 @@
1
+ // -------------------------------------------------------------------
2
+ // TEST - Simple read
3
+ // -------------------------------------------------------------------
4
+ import {RIO, traceCfg, log, sleep, ctrlC, lineNumber} from "../esm/main.mjs"
5
+
6
+ (async () => {
7
+ traceCfg(2)
8
+ const line = lineNumber(2)
9
+ if (line < 0) return
10
+
11
+ // Init input line
12
+ const btn = new RIO(line, "input", {bias: "pull-down"})
13
+ log("button:", btn)
14
+ ctrlC(() => {
15
+ btn.close()
16
+ })
17
+
18
+ log("button value:", btn.read())
19
+ log("input monitoring active for 10s")
20
+ const callback = edge => {
21
+ log("edge:", edge)
22
+ }
23
+ btn.monitoringStart(callback, "both", 30)
24
+ await sleep(10000)
25
+ btn.close()
26
+ })()
27
+
28
+ // -------------------------------------------------------------------
29
+ // EoF
30
+ // -------------------------------------------------------------------
package/test/write.js ADDED
@@ -0,0 +1,29 @@
1
+ // -------------------------------------------------------------------
2
+ // TEST - Simple write
3
+ // -------------------------------------------------------------------
4
+ import {RIO, traceCfg, log, sleep, ctrlC, lineNumber} from "../esm/main.mjs"
5
+
6
+ (async () => {
7
+ traceCfg(2)
8
+
9
+ const line = lineNumber(2)
10
+ if (line < 0) return
11
+
12
+ // Init output line and ctrl+c to close it
13
+ const led = new RIO(line, "output", {value: 0})
14
+ log("led:", led)
15
+ ctrlC(() => {
16
+ led.close()
17
+ })
18
+
19
+ // Turn led on for 3s
20
+ led.write(1)
21
+ log("led turn on")
22
+ await sleep(3000)
23
+ led.write(0)
24
+ log("led turn off")
25
+ led.close()
26
+ })()
27
+ // -------------------------------------------------------------------
28
+ // EoF
29
+ // -------------------------------------------------------------------
package/esm/dev.mjs DELETED
@@ -1,59 +0,0 @@
1
- // -------------------------------------------------------------------
2
- // RPi GPIO CONTROL - DEV TOOLS
3
- // -------------------------------------------------------------------
4
- let debug = {
5
- log: false,
6
- trap: true
7
- }
8
-
9
- // -------------------------------------------------------------------
10
- // FUNCTIONS
11
- /** ------------------------------------------------------------------
12
- * @function nowStr
13
- * @description Return timestamp as formatted string
14
- * @return {String}
15
- */
16
- export const nowStr = () => {
17
- const date = new Date()
18
- return date.toLocaleTimeString() + "." + date.getMilliseconds().toLocaleString('en', {
19
- minimumIntegerDigits: 3,
20
- minimumFractionDigits: 0,
21
- useGrouping: false
22
- })
23
- }
24
-
25
- /** ------------------------------------------------------------------
26
- * @function log
27
- * @description Global customized timestamped console.log
28
- * Requires global variable 'debug'
29
- */
30
- export const log = function () {
31
- if (debug.log)
32
- console.log.apply(console, Array.prototype.concat.apply([nowStr(), "🔎 "], arguments))
33
- }
34
-
35
- /** ------------------------------------------------------------------
36
- * @function trap
37
- * @description Colored log for error messages ⚠️ nodejs only ~ CSS color #F50
38
- */
39
- export const trap = function () {
40
- if (debug.trap)
41
- console.log.apply(console, Array.prototype.concat.apply([nowStr(), "⚠️", "\x1b[38;2;255;80;0m", ...arguments, "\x1b[0m"]))
42
- }
43
-
44
- /** ------------------------------------------------------------------
45
- * @function logCfg
46
- * @description Set log configuration
47
- * @param {Number} level 0: no log, 1: trap only, 2: trap and log
48
- */
49
- export const logCfg = level => {
50
- debug = {
51
- log: false,
52
- trap: false
53
- }
54
- level > 1 ? debug.log = true : false
55
- level > 0 ? debug.trap = true : false
56
- }
57
- // -------------------------------------------------------------------
58
- // EoF
59
- // -------------------------------------------------------------------