Skip to content

Instantly share code, notes, and snippets.

@Hixie
Created February 5, 2020 06:55
Show Gist options
  • Save Hixie/4c6e86b9fa6a7ff34557ffe32bb5e943 to your computer and use it in GitHub Desktop.
Save Hixie/4c6e86b9fa6a7ff34557ffe32bb5e943 to your computer and use it in GitHub Desktop.
Script to track a GQ Geiger Counter and report how long until a radioactive cat is safe to release
#!/usr/bin/perl -wT
use strict;
use Device::SerialPort;
if ($< != 0) {
print("Must be run as root.\n");
exit(1);
}
my $port = Device::SerialPort->new("/dev/ttyUSB0");
$port->baudrate(115200);
$port->databits(8);
$port->parity("none");
$port->stopbits(1);
sub sendCommand {
my($command, $size) = @_;
$port->write("<$command>>");
if ($size > 0) {
my $buffer = '';
do {
my($readCount, $result) = $port->read($size - length($buffer));
$buffer .= $result;
} while (length($buffer) < $size);
return $buffer;
}
}
sub parseInt16 {
my($value) = @_;
my $result = unpack('n', $value);
return $result;
}
my $yearly = 1/(365.25 * 24); # multiplier for microSieverts per year to microSieverts per hour
my $target = 0.2; # microSieverts per hour
my $iodineHalfLife = 8.0197 * 24; # hours
my $device1 = sendCommand('GETVER', 14);
my $device2 = sendCommand('GETVER', 14);
die "Unexpected input from device. Device may not be a GQ Geiger Counter.\n" if ($device1 ne $device2);
print("Connected to: $device1\n");
while (1) {
my $cpm = parseInt16(sendCommand('GETCPM', 2));
my $dosage = $cpm * 6.50 / 1000;
my $equivalent = '';
if ($dosage >= 300000000) {
$equivalent = 'Higher than at Chernobyl during explosion and meltdown.';
} elsif ($dosage >= 100000 * $yearly) { # about 11.4
$equivalent = 'Above dosage level clearly linked to increased cancer risk!';
} if ($dosage >= 50000 * $yearly) { # about 5.7
$equivalent = 'Exceeds maximum yearly dose for US radiation workers.';
} else {
my $halfLives = log2($dosage / $target);
my $hoursRemaining = $halfLives * $iodineHalfLife;
my $daysRemaining = $hoursRemaining / 24;
my $weeksRemaining = $daysRemaining / 7;
if ($weeksRemaining >= 1) {
$equivalent = sprintf('%2.1f weeks remaining', $weeksRemaining);
} elsif ($daysRemaining >= 1) {
$equivalent = sprintf('%1.1f days remaining', $daysRemaining);
} elsif ($hoursRemaining >= 1) {
$equivalent = sprintf('%2.1f hours remaining', $hoursRemaining);
} elsif ($dosage >= 0.85 * 4000 * $yearly) { # about 0.38
$equivalent = 'Above background radiation.';
} else {
$equivalent = 'Background radiation.';
}
}
printf("%6d CPM %5.2f µSv/h %s\n", $cpm, $dosage, $equivalent);
sleep(1);
}
sub log2 {
my($x) = @_;
return log($x)/log(2);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment