#!/usr/bin/ruby -w require "enumerable/statistics" require "serialport" SENSOR_BITS = 12 SENSOR_MAX = (1 << SENSOR_BITS) - 1 $stdout.sync = true def log(msg) $stdout.write("#{Time.now.strftime("%H:%M:%S")} #{msg}\n") $stdout.flush end sensors = [] SerialPort.open("/dev/ttyACM1", 115200, 8, 1, SerialPort::NONE) do | port | log("Allowing sensors to settle...") sleep(3) begin port.read_nonblock(16 << 20) rescue IO::WaitReadable end port.readline log("Reading soil moisture sensors...") 10.times do raw = port.readline raise "Cannot parse sensor results #{raw.inspect}" unless raw =~ /\[([^\]]+)\]/ sensors << $1.split(/\s+/).filter { | x | not x.empty? }.map { | x | x.to_i } log("Raw sensor results: \t#{sensors[-1].join("\t")}") end end avgsensors = [] stdsensors = [] sensors.transpose.each do | sensor | avgsensors << sensor.mean.round stdsensors << sensor.stdev.round end log("Avg sensor results: \t#{avgsensors.join("\t")} \t(per sensor)") log("SDv sensor results: \t#{stdsensors.join("\t")} \t(per sensor)") avg = sensors.flatten.mean.round std = sensors.flatten.stdev.round log("Avg sensor results: \t#{avg} \t(#{(100.0 * avg.to_f / SENSOR_MAX.to_f).round}%) \t(overall)") log("SDv sensor results: \t#{std} \t(overall)")