lgpio 0.1.4 → 0.1.5

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 84493ab6ca425d960887480b8f186a610fd9e41f0885657c79b5a4038a8a2035
4
- data.tar.gz: 705d88399e518bdbc167eca65cd795dea2d33936b919aaaf22a34c8be032a1a1
3
+ metadata.gz: 984afd62543a10d3fc0b6d2a9a581b05b4d9bf7c159d2747f990b2247b59aef1
4
+ data.tar.gz: d2431adb24613fdd42b9f9f06a428c399fe48be2e215a13463237a798113630c
5
5
  SHA512:
6
- metadata.gz: 77f3c42ed9a94f8ea0c59acc2cb276efd400990099ac4272f06619645953f6014dbc4a9330d04ed154eee86fabba4791290fcd7201b326f2d6f4b2437a5d5812
7
- data.tar.gz: 7fd2aa6715e36f3e95d35248b1b13ffb141dca3c50b1ab7a5fbe2e420b67a3873d3de50a24b5eda460a50bd69133492043356715522b27cbe509e280c3174699
6
+ metadata.gz: f32ceb3af8218d26f1f5713302a9891365af498fe76e2a750037f2ae10a437b747b40167e9fd9c5170fc28696d90c9244ce5d9a36269eba0d0c827a79be47fcd
7
+ data.tar.gz: b167ef512729754b46dd3cd14750dd715c8541987014a254465c72619f1ead5d4ae8ff74bcbb6c9122b331c5f65a159e0f0c9890f9e0ad7a5b582dafe2763e54
data/README.md CHANGED
@@ -2,24 +2,29 @@
2
2
 
3
3
  Ruby bindings for the [lgpio (lg)](https://github.com/joan2937/lg) Linux library, running on single board computers (SBCs), like Raspberry Pi.
4
4
 
5
- ## Standard LGPIO Functions
5
+ ## Mapped LGPIO Features
6
6
  - [x] GPIO Read/Write
7
7
  - [x] GPIO Group Read/Write
8
8
  - [x] GPIO Alerts / Callbacks
9
- - lg generates alerts at high speed, in a separate thread. In Ruby, they can be read from a queue as part of your application loop.
10
- - [x] PWM Output
11
- - Software timed on any pin. No interface for hardware PWM yet.
9
+ - lg generates alerts at high speed in a separate thread. You can read them from a queue in Ruby, as part of your application loop.
10
+ - [x] Software PWM Out
11
+ - Software timed (not 100% precise), on any pin
12
+ - Not recommended for servo motors
12
13
  - [x] Wave
13
14
  - Software timed on any pin, as with PWM.
14
15
  - [x] I2C
15
16
  - [x] SPI
16
17
 
17
- ## Extras
18
+ ## Extra Features, based on LGPIO
18
19
  - [x] WS2812 over SPI
19
20
  - Only outputs on a SPI MOSI pin. Must be able to set SPI clock frequency to 2.4 MHz.
20
21
  - [ ] Bit Bang SPI
21
22
  - [ ] Bit Bang I2C
22
23
 
24
+ ## Sysfs PWM Interface Features
25
+ - [x] Hardware PWM Out (specific pins per chip)
26
+ - [x] Servo
27
+
23
28
  ## Installation
24
29
  On Debian-based Linuxes (RaspberryPi OS, Armbian, DietPi etc.):
25
30
  ```bash
@@ -1,6 +1,6 @@
1
1
  require 'lgpio'
2
2
 
3
- I2C_DEV = 2
3
+ I2C_DEV = 3
4
4
  POWER_ON_DELAY = 0.100
5
5
  RESET_DELAY = 0.020
6
6
  COMMAND_DELAY = 0.010
@@ -1,6 +1,6 @@
1
1
  require 'lgpio'
2
2
 
3
- I2C_DEV = 2
3
+ I2C_DEV = 3
4
4
  POWER_ON_DELAY = 0.100
5
5
  RESET_DELAY = 0.020
6
6
  COMMAND_DELAY = 0.010
@@ -1,6 +1,6 @@
1
1
  require 'lgpio'
2
2
 
3
- I2C_DEV = 2
3
+ I2C_DEV = 3
4
4
  INIT_ARRAY = [0, 168, 63, 211, 0, 64, 161, 200, 218, 18, 164, 166, 213, 128, 219, 32, 217, 241, 141, 20, 32, 0, 175]
5
5
  START_ARRAY = [0, 33, 0, 127, 34, 0, 7]
6
6
  BLANK_ARRAY = [64] + Array.new(1024) { 0 }
data/examples/servo.rb ADDED
@@ -0,0 +1,36 @@
1
+ require 'lgpio'
2
+ #
3
+ # Writing directly to a hardware PWM channel to control a servo.
4
+ # Arguments in order are:
5
+ # pwmchip index (X in /sys/class/pwm/pwmchipX/)
6
+ # PWM channel on the chip (Y in /sys/class/pwm/pwmchipX/pwmY)
7
+ # period: given in nanoseconds
8
+ # OR frequency: given in Hz
9
+ #
10
+ servo = LGPIO::HardwarePWM.new(0, 1, period: 20_000_000)
11
+ #
12
+ # Duty cycle is given in nanoseconds by default. Extra setter methods
13
+ # are provided for microseconds, and percent.
14
+ #
15
+ # servo.duty_percent = 2.5
16
+ # servo.duty_us = 500
17
+ servo.duty = 500_000
18
+
19
+ #
20
+ # Using the Servo class instead.
21
+ # Arguments in order are:
22
+ # pwmchip index (X in /sys/class/pwm/pwmchipX/)
23
+ # PWM channel on the chip (Y in /sys/class/pwm/pwmchipX/pwmY)
24
+ # Minimum servo duty cycle in microseconds
25
+ # Maximum servo duty cicle in microseconds
26
+ # Minimum servo angle
27
+ # Maximum servo angle
28
+ #
29
+ servo = LGPIO::PositionalServo.new(0, 1, 500, 2500, 0, 180)
30
+
31
+ angles = [0, 30, 60, 90, 120, 150, 180, 150, 120, 90, 60, 30]
32
+
33
+ angles.cycle do |angle|
34
+ servo.angle = angle
35
+ sleep 1
36
+ end
@@ -0,0 +1,70 @@
1
+ module LGPIO
2
+ class HardwarePWM
3
+ NS_PER_S = 1_000_000_000
4
+ NS_PER_US = 1_000
5
+ SYS_FS_PWM_PATH = "/sys/class/pwm/"
6
+
7
+ attr_reader :period, :duty, :enabled
8
+
9
+ def initialize(chip, channel, frequency: nil, period: nil)
10
+ @chip = chip
11
+ @channel = channel
12
+
13
+ # Accept either frequency (in Hz) or period in nanoseconds.
14
+ if (frequency && period) || (!frequency && !period)
15
+ raise "either period: or frequency: is required, but not both"
16
+ end
17
+
18
+ period ? self.period = period : self.frequency = frequency
19
+ enable
20
+ end
21
+
22
+ def path
23
+ @path ||= "#{SYS_FS_PWM_PATH}pwmchip#{@chip}/pwm#{@channel}/"
24
+ end
25
+
26
+ def frequency=(freq)
27
+ self.period = (NS_PER_S / freq.to_f).round
28
+ end
29
+
30
+ def period=(p)
31
+ old_period = File.read("#{path}period").strip.to_i
32
+ unless (old_period == 0)
33
+ File.open("#{path}duty_cycle", 'w') { |f| f.write("0") }
34
+ end
35
+ File.open("#{path}period", 'w') { |f| f.write(p) }
36
+ @period = p
37
+ end
38
+
39
+ def duty_percent
40
+ (duty / period.to_f) * 100.0
41
+ end
42
+
43
+ def duty_percent=(d)
44
+ raise "duty_cycle: #{d} % cannot be more than 100%" if d > 100
45
+ d_ns = ((d / 100.0) * @period.to_i).round
46
+ self.duty = d_ns
47
+ end
48
+
49
+ def duty_us=(d_us)
50
+ d_ns = (d_us * NS_PER_US).round
51
+ self.duty = d_ns
52
+ end
53
+
54
+ def duty=(d_ns)
55
+ raise "duty cycle: #{d_ns} ns cannot be longer than period: #{period} ns" if d_ns > period
56
+ File.open("#{path}duty_cycle", 'w') { |f| f.write(d_ns) }
57
+ @duty = d_ns
58
+ end
59
+
60
+ def disable
61
+ File.open("#{path}enable", 'w') { |f| f.write("0") }
62
+ @enabled = false
63
+ end
64
+
65
+ def enable
66
+ File.open("#{path}enable", 'w') { |f| f.write("1") }
67
+ @enabled = true
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,28 @@
1
+ module LGPIO
2
+ class PositionalServo < HardwarePWM
3
+ FREQUENCY = 50
4
+
5
+ attr_reader :angle
6
+
7
+ def initialize(chip, channel, min_us, max_us, min_angle, max_angle)
8
+ super(chip, channel, frequency: FREQUENCY)
9
+
10
+ raise "min_us: #{min_us} cannot be lower than max_us: #{max_us}" if max_us < min_us
11
+ @min_us = min_us
12
+ @max_us = max_us
13
+ @us_range = @max_us - @min_us
14
+
15
+ @min_angle = min_angle
16
+ @max_angle = max_angle
17
+ end
18
+
19
+ def angle=(a)
20
+ ratio = (a - @min_angle).to_f / (@max_angle - @min_angle)
21
+ raise "angle: #{a} outside servo range" if (ratio < 0) || (ratio > 1)
22
+
23
+ d_us = (@us_range * ratio) + @min_us
24
+ self.duty_us = d_us
25
+ @angle = a
26
+ end
27
+ end
28
+ end
data/lib/lgpio/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module LGPIO
2
- VERSION = "0.1.4"
2
+ VERSION = "0.1.5"
3
3
  end
data/lib/lgpio.rb CHANGED
@@ -1,4 +1,7 @@
1
1
  require_relative 'lgpio/lgpio'
2
+ require_relative 'lgpio/version'
3
+ require_relative 'lgpio/hardware_pwm'
4
+ require_relative 'lgpio/positional_servo'
2
5
 
3
6
  module LGPIO
4
7
  LOW = 0
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lgpio
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - vickash
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-08-05 00:00:00.000000000 Z
11
+ date: 2024-08-17 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Use GPIO / PWM / I2C / SPI / UART on Linux SBCs in Ruby
14
14
  email: mail@vickash.com
@@ -34,6 +34,7 @@ files:
34
34
  - examples/reports.rb
35
35
  - examples/rotary_encoder.rb
36
36
  - examples/rotary_encoder_led.rb
37
+ - examples/servo.rb
37
38
  - examples/spi_loopback.rb
38
39
  - examples/spi_read.rb
39
40
  - examples/spi_ws2812.rb
@@ -43,6 +44,8 @@ files:
43
44
  - ext/lgpio/lgpio.c
44
45
  - lgpio.gemspec
45
46
  - lib/lgpio.rb
47
+ - lib/lgpio/hardware_pwm.rb
48
+ - lib/lgpio/positional_servo.rb
46
49
  - lib/lgpio/version.rb
47
50
  homepage: https://github.com/denko-rb/lgpio
48
51
  licenses: