Skip to content

Instantly share code, notes, and snippets.

@cho45
Created December 14, 2016 00:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cho45/f9dd746c5d9d7943958fdb3f6416e36f to your computer and use it in GitHub Desktop.
Save cho45/f9dd746c5d9d7943958fdb3f6416e36f to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
require 'serialport'
class MH_Z19
STARTING_BYTE = 0xff
CMD_GAS_CONCENTRATION = 0x86
CMD_CALIBRATE_ZERO_POINT = 0x87
CMD_CALIBRATE_SPAN_POINT = 0x88
class GenericException < Exception; end
class InvalidPacketException < GenericException; end
def initialize(io, sensor_id: 0x01)
if io.is_a? String
@io = SerialPort.new(
io,
9600,
8,
1,
0
)
@io.flow_control = SerialPort::NONE
@io.set_encoding(Encoding::BINARY)
else
@io = io
end
@sensor_id = sensor_id
end
def close
@io.close
end
def gas_concentration
packet = Array.new(9) { 0 }
packet[0] = STARTING_BYTE
packet[1] = @sensor_id
packet[2] = CMD_GAS_CONCENTRATION
packet[8] = checksum(packet)
@io.write packet.pack("C*")
raw_packet = @io.read(9)
raise InvalidPacketException, "packet seems nil" if raw_packet.nil?
packet = raw_packet.unpack("C*")
sum = checksum(packet)
unless packet[8] == sum
raise InvalidPacketException, "packet checksum is invalid"
end
(packet[2] << 8) | packet[3]
end
def calibrate_zero_point
packet = Array.new(9) { 0 }
packet[0] = STARTING_BYTE
packet[1] = @sensor_id
packet[2] = CMD_CALIBRATE_ZERO_POINT
packet[8] = checksum(packet)
@io.write packet.pack("C*")
# no return value
nil
end
def calibrate_span_point(span_point)
packed = [span_point].pack("n")
packet = Array.new(9) { 0 }
packet[0] = STARTING_BYTE
packet[1] = @sensor_id
packet[2] = CMD_CALIBRATE_SPAN_POINT
packet[3] = packet[0]
packet[4] = packet[1]
packet[8] = checksum(packet)
@io.write packet.pack("C*")
# no return value
nil
end
private
def checksum(packet)
raise InvalidPacketException, "invalid packet size" unless packet.size == 9
sum = 0
(1...8).each do |i|
sum = (sum + packet[i]) & 0xff
end
sum = 0xff - sum
sum += 1
sum
end
end
if ENV['PORT'].nil?
require 'socket'
s1, s2 = Socket.pair(:UNIX, :STREAM, 0)
Thread.start do
Thread.abort_on_exception = true
while packet = s2.read(9)
case packet
when "\xFF\x01\x86\x00\x00\x00\x00\x00y".b
ret = "\xFF\x86\x02\x60\x47\x00\x00\x00\xd1"
s2.write(ret)
else
raise "unknown packet #{packet.inspect}"
end
end
end
co2 = MH_Z19.new(s1)
p co2.gas_concentration
end
require 'net/http'
require 'uri'
uri = URI(ENV['GF_URI']) rescue nil
co2 = MH_Z19.new(ENV['PORT'])
loop do
begin
ppm = co2.gas_concentration
p ppm
unless uri.nil?
res = Net::HTTP.post_form(uri, 'number' => ppm)
p res
end
rescue => e
p e
puts e.backtrace
end
sleep 1
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment