Class: ObjectOrientedBeagleboneBlack::Pwm

Inherits:
Object
  • Object
show all
Defined in:
lib/object_oriented_beaglebone_black/pwm.rb

Defined Under Namespace

Modules: Polarity

Constant Summary collapse

PWM_DEVICE_TREE_OVERLAY_PARAMETER =
"am33xx_pwm"

Instance Method Summary collapse

Constructor Details

#initialize(pin_key) ⇒ Pwm

Returns a new instance of Pwm.



13
14
15
16
17
18
# File 'lib/object_oriented_beaglebone_black/pwm.rb', line 13

def initialize(pin_key)
  @pin_key = pin_key
  @slots_file_path = File.join(File.join(OBJECT_ORIENTED_BEAGLEBONE_BLACK_CONFIG["slots_directory"], "slots"))

  activate_device_tree_overlays
end

Instance Method Details

#activate_device_tree_overlaysObject



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/object_oriented_beaglebone_black/pwm.rb', line 20

def activate_device_tree_overlays
  # Note: Since slots file acts as an interface to activate Device Tree Overlay, simply writing to it does what needs to be done. 
  #       I'm using appending here so that testing in a local environment becomes straightfoward. 

  puts "This can take several seconds for necessary setups..."

  slots_file = File.open(@slots_file_path, "a+")
  slots_file_content = slots_file.read

  unless slots_file_content.include? PWM_DEVICE_TREE_OVERLAY_PARAMETER
  # until slots_file_content.include? PWM_DEVICE_TREE_OVERLAY_PARAMETER

    # Just in case where the previous read session is not fully completed.
    sleep 1

    slots_file.write(PWM_DEVICE_TREE_OVERLAY_PARAMETER)

    # It seems to take a time to load the device tree overlay. Wait for two seconds.
    sleep 2

    # Note: Sometime, the file pointer seems to be at the end of the file and doesn't read the file content before that. 
    # slots_file_content = slots_file.read

  end

  # Note: Closing this file sometimes causes an error in BeagleBone Black:
  #   Errno::ENOENT: No such file or directory @ fptr_finalize - /sys/devices/bone_capemgr.9/slots
  begin
    slots_file.close if File.exist?(@slots_file_path) && !slots_file.closed?
  rescue SystemCallError => system_call_error_message
    puts "Error happened while closing #{@slots_file_path} with the message: #{system_call_error_message}"
  end

  # Just in case
  sleep 1

  puts "First step of setups done."

  pwm_pin_device_tree_overlay_parameter = "bone_pwm_#{@pin_key}"

  slots_file = File.open(@slots_file_path, "a+")
  slots_file_content = slots_file.read

  unless slots_file_content.include? pwm_pin_device_tree_overlay_parameter
  # until slots_file_content.include? pwm_pin_device_tree_overlay_parameter

    # Just in case where the previous read session is not fully completed.
    sleep 1

    slots_file.write(pwm_pin_device_tree_overlay_parameter)

    # It seems to take a time to load the device tree overlay. Wait for one second.
    sleep 2

    # Note: Sometime, the file pointer seems to be at the end of the file and doesn't read the file content before that.
    # slots_file_content = slots_file.read

  end

  # Note: Closing this file sometimes causes an error in BeagleBone Black:
  #   Errno::ENOENT: No such file or directory @ fptr_finalize - /sys/devices/bone_capemgr.9/slots
  begin
    slots_file.close if File.exist?(@slots_file_path) && !slots_file.closed?
  rescue SystemCallError => system_call_error_message
    puts "Error happened while closing #{@slots_file_path} with the message: #{system_call_error_message}"
  end

  puts "Setups done."

end

#duty_cycleObject



98
99
100
101
102
103
104
# File 'lib/object_oriented_beaglebone_black/pwm.rb', line 98

def duty_cycle
  # Using this instead of simple "File.open(file_path).read" in order to close file after reading.
  internal_duty_value = nil
  File.open(File.join(pwm_directory, "duty"), "r") { |file| internal_duty_value = file.read.strip }
  duty_cycle = (BigDecimal(internal_duty_value.to_s) / BigDecimal(period.to_s)).to_f
  duty_cycle
end

#duty_cycle=(duty_cycle) ⇒ Object

duty_cycle (value between 0 and 1)



92
93
94
95
96
# File 'lib/object_oriented_beaglebone_black/pwm.rb', line 92

def duty_cycle=(duty_cycle)
  self.polarity = ObjectOrientedBeagleboneBlack::Pwm::Polarity::DIRECT
  internal_duty_value = (BigDecimal(duty_cycle.to_s) * BigDecimal(period.to_s)).to_i
  File.open(File.join(pwm_directory, "duty"), "w") { |file| file.write(internal_duty_value) }
end

#periodObject

Unit: [ns] (nano second)



128
129
130
131
132
# File 'lib/object_oriented_beaglebone_black/pwm.rb', line 128

def period
  internal_period_value = nil
  File.open(File.join(pwm_directory, "period"), "r") { |file| internal_period_value = file.read.strip.to_i }
  internal_period_value
end

#period=(period) ⇒ Object



116
117
118
119
120
121
122
123
124
125
# File 'lib/object_oriented_beaglebone_black/pwm.rb', line 116

def period=(period)
  current_duty_cycle = self.duty_cycle

  File.open(File.join(pwm_directory, "period"), "w") { |file| file.write(period) }
  
  # Preserves the duty cycle:
  # Note: Internally in BeagleBone Black, "duty" value is relative to "period" value. 
  #       e.g. For "period" = 1000, "duty" = 500 gives the duty cycle = 500 / 1000 = 0.5.
  self.duty_cycle = current_duty_cycle
end

#polarityObject



110
111
112
113
114
# File 'lib/object_oriented_beaglebone_black/pwm.rb', line 110

def polarity
  internal_polarity_value = nil
  File.open(File.join(pwm_directory, "polarity"), "r") { |file| internal_polarity_value = file.read.strip.to_i }
  internal_polarity_value
end

#polarity=(polarity) ⇒ Object



106
107
108
# File 'lib/object_oriented_beaglebone_black/pwm.rb', line 106

def polarity=(polarity)
  File.open(File.join(pwm_directory, "polarity"), "w") { |file| file.write(polarity) }
end