module GrovePi
Constants
- A0
Arduino pin mappings.
- A1
- A2
- CMD_4DIG_BRIGHTNESS
- CMD_4DIG_CLOCK
- CMD_4DIG_DIGIT
- CMD_4DIG_INIT
- CMD_4DIG_LEDS
- CMD_4DIG_ON
- CMD_4DIG_VALUE
- CMD_4DIG_VALUE_ZEROS
- CMD_PIN_MODE
- CMD_READ_ANALOG
- CMD_READ_DIGITAL
Commands.
- CMD_READ_FIRMWARE_VERSION
- CMD_READ_TEMP_HUM
- CMD_ULTRASONIC_READ
- CMD_WRITE_ANALOG
- CMD_WRITE_DIGITAL
- CONFIG_RETRIES
Configuration settings.
- D2
- D3
- D4
- D5
- D6
- D7
- D8
- DISPLAY_RGB_ADDRESS
- DISPLAY_TEXT_ADDRESS
LCD RGB display - I2C addresses
- GROVE_PI_I2C_SLAVE_ADDRESS
- LOCK_FILE_PATH
Initialize the lock file path.
- LOCK_REQUEST_PATH
- PINS_ANALOG
- PINS_DIGITAL
- PIN_MODE_IN
Pin modes.
- PIN_MODE_OUT
Public Class Methods
# File lib/templates/grove_pi/grove_pi.rb, line 190 def self._ensure_init() if @_i2c_grove_pi == nil @_i2c_grove_pi = self._grove_pi_init if @_i2c_grove_pi == nil raise 'No GrovePi found.' end end GrovePi.get_lock end
Internal functions.
These functions are not intended to be used directly by the user but by the functions which are exposed to the user.
# File lib/templates/grove_pi/grove_pi.rb, line 87 def self._grove_pi_discover() begin i2c_device_files = Dir['/dev/i2c-*'] if i2c_device_files.length < 1 return false, nil end # Iterate over I2C device files. for f in i2c_device_files device_file = f f = f.strip f.slice! '/dev/i2c-' lines = %x(#{'i2cdetect -y ' + Integer(f).to_s}).split("\n") # Get rid of the first line. lines.shift if lines.length < 1 next end # Process i2cdetect command output for the I2C device file. for i in 0..lines.length - 1 line = lines[i].strip line = line.split ':' if line.length != 2 next end for i2c_address in line[1].split(' ') begin if Integer(i2c_address) == GROVE_PI_I2C_SLAVE_ADDRESS return true, device_file.strip end rescue next end end end end rescue return false, nil end return false, nil end
# File lib/templates/grove_pi/grove_pi.rb, line 179 def self._grove_pi_init() status, i2c_device_file = self._grove_pi_discover if status && i2c_device_file != nil return I2CDevice.new address: GROVE_PI_I2C_SLAVE_ADDRESS, driver: I2CDevice::Driver::I2CDev.new(i2c_device_file) else return nil end end
# File lib/templates/grove_pi/grove_pi.rb, line 206 def self._read_analog(pin) self._ensure_init @_i2c_grove_pi.i2cset @_i2c_grove_pi.address, CMD_READ_ANALOG, pin, 0, 0 read_value = @_i2c_grove_pi.i2cget(@_i2c_grove_pi.address, 3) GrovePi.release_lock if read_value != nil bytes = read_value.chars return (bytes[1].ord * 256) + bytes[2].ord else return 65535 end end
# File lib/templates/grove_pi/grove_pi.rb, line 225 def self._read_digital(pin) self._ensure_init @_i2c_grove_pi.i2cset @_i2c_grove_pi.address, CMD_READ_DIGITAL, pin, 0, 0 val = @_i2c_grove_pi.i2cget(@_i2c_grove_pi.address, 2) GrovePi.release_lock if val != nil return val.chars[0].ord else return 0 end end
# File lib/templates/grove_pi/grove_pi.rb, line 200 def self._set_pin_mode(pin, mode) self._ensure_init @_i2c_grove_pi.i2cset @_i2c_grove_pi.address, CMD_PIN_MODE, pin, mode, 0 GrovePi.release_lock end
# File lib/templates/grove_pi/grove_pi.rb, line 219 def self._write_analog(pin, value) self._ensure_init @_i2c_grove_pi.i2cset @_i2c_grove_pi.address, CMD_WRITE_ANALOG, pin, value, 0 GrovePi.release_lock end
# File lib/templates/grove_pi/grove_pi.rb, line 237 def self._write_digital(pin, value) self._ensure_init @_i2c_grove_pi.i2cset @_i2c_grove_pi.address, CMD_WRITE_DIGITAL, pin, value, 0 GrovePi.release_lock end
Display digits and center colon
string can contain digits (0-9)
# File lib/templates/grove_pi/grove_pi.rb, line 543 def self.fourDigit_displayClock(pin, string) self._ensure_init string.delete! ":" # make sure there is no colon in the string value = string.to_i left = value/100 right = value % 100 @_i2c_grove_pi.i2cset(@_i2c_grove_pi.address, CMD_4DIG_CLOCK, pin, left, right) self.release_lock return left, right end
Display a decimal value without leading zeros
value = 0 - 9999
# File lib/templates/grove_pi/grove_pi.rb, line 487 def self.fourDigit_displayDec(pin, string) self._ensure_init value = string.to_i # split into 2 bytes byte1 = value & 255 byte2 = value >> 8 @_i2c_grove_pi.i2cset(@_i2c_grove_pi.address, CMD_4DIG_VALUE, pin, byte1, byte2) sleep(0.05) GrovePi.release_lock end
Turn on entire display (88:88)
# File lib/templates/grove_pi/grove_pi.rb, line 478 def self.fourDigit_displayOn(pin) self._ensure_init @_i2c_grove_pi.i2cset(@_i2c_grove_pi.address, CMD_4DIG_ON, pin, 0, 0) sleep(0.05) GrovePi.release_lock end
Display a string
string can consist of 0-9
# File lib/templates/grove_pi/grove_pi.rb, line 503 def self.fourDigit_displayString(pin, string) self._ensure_init if string.include? ":" string.delete ":" end digits = string.chars i = 0 while (digits.length < 4) digits.unshift(" ") end #for each space added or each unaccepted character, display an empty space #otherwise display the character digits.each do |digit| if (digit == " ") | ((digit.to_i(16) == 0) & (digit != "0")) @_i2c_grove_pi.i2cset(@_i2c_grove_pi.address, CMD_4DIG_LEDS, pin, i, 0) else @_i2c_grove_pi.i2cset(@_i2c_grove_pi.address, CMD_4DIG_DIGIT, pin, i, digit.to_i(16)) end i += 1 sleep(0.05) end GrovePi.release_lock end
Initialize four-digit display
# File lib/templates/grove_pi/grove_pi.rb, line 460 def self.fourDigit_init(pin) self._ensure_init @_i2c_grove_pi.i2cset(@_i2c_grove_pi.address, CMD_4DIG_INIT, pin, 0, 0) GrovePi.release_lock end
Set brightness of display
brightness = 0-7
# File lib/templates/grove_pi/grove_pi.rb, line 533 def self.fourDigit_setBrightness(pin, brightness) self._ensure_init @_i2c_grove_pi.i2cset(@_i2c_grove_pi.address, CMD_4DIG_BRIGHTNESS, pin, brightness.to_i, 0) sleep(0.05) GrovePi.release_lock end
Set individual digit
segment = 0-3 value = 0-15 or 0-F
# File lib/templates/grove_pi/grove_pi.rb, line 470 def self.fourDigit_writeDigit(pin, segment, value) self._ensure_init @_i2c_grove_pi.i2cset(@_i2c_grove_pi.address, CMD_4DIG_DIGIT, pin, segment, value) sleep(0.05) GrovePi.release_lock end
# File lib/templates/grove_pi/grove_pi.rb, line 136 def self.get_lock cycle = true wait = false while cycle == true begin #puts "Getting lock." unless @@_lock_request == false && File.exist?(LOCK_REQUEST_PATH) @@_i2c_device_file = File.open(LOCK_FILE_PATH, File::WRONLY|File::CREAT|File::EXCL) if @@_lock_request == true File.delete(LOCK_REQUEST_PATH) end @@_lock_request = false end if wait == true i = 0 while i < 1000000 i += 1 end wait = false end cycle = false #puts "Lock acquired." rescue #puts "Could not get lock." unless File.exist?(LOCK_REQUEST_PATH) File.open(LOCK_REQUEST_PATH, File::WRONLY|File::CREAT) end @@_lock_request = true wait = true end end end
Analog read functions.
# File lib/templates/grove_pi/grove_pi.rb, line 246 def self.read_analog(pin) if !PINS_ANALOG.include? pin raise 'Invalid analog pin.' end for i in 0..CONFIG_RETRIES - 1 begin self._set_pin_mode pin, PIN_MODE_IN return self._read_analog pin rescue Errno::EREMOTEIO next end end end
Digital read function.
# File lib/templates/grove_pi/grove_pi.rb, line 279 def self.read_digital(pin) if !PINS_DIGITAL.include? pin raise 'Invalid digital pin.' end for i in 0..CONFIG_RETRIES - 1 begin self._set_pin_mode pin, PIN_MODE_IN return self._read_digital pin rescue => e puts e.message next end end end
Miscellaneous functions.
# File lib/templates/grove_pi/grove_pi.rb, line 359 def self.read_firmware_version() for i in 0..CONFIG_RETRIES - 1 begin self._ensure_init @_i2c_grove_pi.i2cset @_i2c_grove_pi.address, CMD_READ_FIRMWARE_VERSION, 0, 0, 0 read_value = @_i2c_grove_pi.i2cget(@_i2c_grove_pi.address, 4) GrovePi.release_lock if read_value != nil bytes = read_value.chars return [bytes[1].ord, bytes[2].ord, bytes[3].ord] else raise "Firmware version could not be read." end rescue Errno::EREMOTEIO next end end end
Functions for reading and writing I2C slaves connected to I2C-1, I2C-2 or I2C-3 ports of the GrovePi
.
# File lib/templates/grove_pi/grove_pi.rb, line 314 def self.read_grove_pi_i2c(i2c_slave_address, length) _ensure_init if !@_i2c_slave_addresses.key?(i2c_slave_address) path = @_i2c_grove_pi.instance_variable_get(:@driver) .instance_variable_get(:@path) @_i2c_slave_addresses[i2c_slave_address] = I2CDevice.new address: i2c_slave_address, driver: I2CDevice::Driver::I2CDev.new(path) end bytes = [] read_value = @_i2c_slave_addresses[i2c_slave_address].i2cget(i2c_slave_address, length) GrovePi.release_lock if read_value != nil _bytes = read_value.chars for b in _bytes bytes << b.ord end return bytes else return ["0".ord] end end
Read temperature and humidity values from sensor
# File lib/templates/grove_pi/grove_pi.rb, line 410 def self.read_temp_humidity(pin, sensor_version) self._ensure_init # if sensor is white: module_type = 1, if sensor is blue: module_type = 0 if sensor_version == "white" module_type = 1 else module_type = 0 end error = false begin @_i2c_grove_pi.i2cset(@_i2c_grove_pi.address, CMD_READ_TEMP_HUM, pin, module_type, 0) rescue => e puts e.message error = true end if error == false for i in 0..CONFIG_RETRIES - 1 begin # read one byte @_i2c_grove_pi.i2cget(@_i2c_grove_pi.address, 1) # read 10 more bytes number = @_i2c_grove_pi.i2cget(@_i2c_grove_pi.address, 9) GrovePi.release_lock if !number.nil? temp_value = number[1..4].unpack('f')[0].round(2) * 9/5 + 32 #convert to F humidity_value = number[5..8].unpack('f')[0].round(2) return temp_value, humidity_value else return 0.0, -100.0 end rescue Errno::EREMOTEIO next end end end end
# File lib/templates/grove_pi/grove_pi.rb, line 169 def self.release_lock #puts "Releasing lock." if @@_i2c_device_file.is_a?(File) @@_i2c_device_file.close File.delete(LOCK_FILE_PATH) @@_i2c_device_file = nil #puts "Lock released." end end
Set the color of the LCD RGB display
red = 0-255 green = 0-255 blue = 0-255
# File lib/templates/grove_pi/grove_pi.rb, line 579 def self.setRGB(red,green,blue) write_lcd_rgb_i2c(DISPLAY_RGB_ADDRESS, 0, 0) write_lcd_rgb_i2c(DISPLAY_RGB_ADDRESS, 1, 0) write_lcd_rgb_i2c(DISPLAY_RGB_ADDRESS, 0x08, 0xaa) write_lcd_rgb_i2c(DISPLAY_RGB_ADDRESS, 4, red.to_i) write_lcd_rgb_i2c(DISPLAY_RGB_ADDRESS, 3, green.to_i) write_lcd_rgb_i2c(DISPLAY_RGB_ADDRESS, 2, blue.to_i) end
Set the text on the LCD RGB display
# File lib/templates/grove_pi/grove_pi.rb, line 589 def self.setText(text) write_lcd_rgb_i2c(DISPLAY_TEXT_ADDRESS, 0x80, 0x01) sleep(0.05) write_lcd_rgb_i2c(DISPLAY_TEXT_ADDRESS, 0x80, 0x08 | 0x04) write_lcd_rgb_i2c(DISPLAY_TEXT_ADDRESS, 0x80, 0x28) sleep(0.05) count = 0 row = 0 text.chars.each do |c| if c == '\n' or count == 16 count = 0 row += 1 if row == 2 break end write_lcd_rgb_i2c(DISPLAY_TEXT_ADDRESS, 0x80, 0xc0) if c == '\n' next end end count += 1 write_lcd_rgb_i2c(DISPLAY_TEXT_ADDRESS, 0x40, c.ord) end end
Read distance from ultrasonic ranger
# File lib/templates/grove_pi/grove_pi.rb, line 387 def self.ultrasonic_read(pin) self._ensure_init @_i2c_grove_pi.i2cset(@_i2c_grove_pi.address, CMD_ULTRASONIC_READ, pin, 0, 0) sleep(0.06) #firmware has a time of 50ms so wait for more than that @_i2c_grove_pi.i2cget(@_i2c_grove_pi.address, 1) GrovePi.release_lock read_value = @_i2c_grove_pi.i2cget(@_i2c_grove_pi.address, 3) if read_value != nil numbers = read_value.chars return (numbers[1].ord) * 256 + (numbers[2].ord) else return 0 end end
Analog write functions (PWM on digital pins D3
, D5
and D6
).
# File lib/templates/grove_pi/grove_pi.rb, line 262 def self.write_analog(pin, value) if !PINS_DIGITAL.include? pin raise 'Invalid analog pin. Note: PWM based analog write is applicable on digital ports.' end for i in 0..CONFIG_RETRIES - 1 begin self._set_pin_mode pin, PIN_MODE_OUT self._write_analog pin, value return rescue Errno::EREMOTEIO next end end end
Digital write function.
# File lib/templates/grove_pi/grove_pi.rb, line 296 def self.write_digital(pin, value) if !PINS_DIGITAL.include? pin raise 'Invalid digital pin.' end for i in 0..CONFIG_RETRIES - 1 begin self._set_pin_mode pin, PIN_MODE_OUT self._write_digital pin, value return rescue Errno::EREMOTEIO next end end end
# File lib/templates/grove_pi/grove_pi.rb, line 342 def self.write_grove_pi_i2c(i2c_slave_address, *data) _ensure_init if !@_i2c_slave_addresses.key?(i2c_slave_address) path = @_i2c_grove_pi.instance_variable_get(:@driver) .instance_variable_get(:@path) @_i2c_slave_addresses[i2c_slave_address] = I2CDevice.new address: i2c_slave_address, driver: I2CDevice::Driver::I2CDev.new(path) end @_i2c_slave_addresses[i2c_slave_address].i2cset i2c_slave_address, *data GrovePi.release_lock end
Helper function for communicating with LCD RGB display
# File lib/templates/grove_pi/grove_pi.rb, line 559 def self.write_lcd_rgb_i2c(i2c_slave_address, *data) self._ensure_init if !@_i2c_slave_addresses.key?(i2c_slave_address) path = @_i2c_grove_pi.instance_variable_get(:@driver) .instance_variable_get(:@path) @_i2c_slave_addresses[i2c_slave_address] = I2CDevice.new address: i2c_slave_address, driver: I2CDevice::Driver::I2CDev.new(path) end @_i2c_slave_addresses[i2c_slave_address].i2cset *data GrovePi.release_lock end