Summary
A minimal application for uploading the Geiger Counter's current CPM values to gmcmap.com. Written in Rust.
→ GitHub
Features:
- Only specify the port, user ID and Geiger Counter ID – and you are good to go
- Minimal dependencies
- Easy to adapt to specific needs or other models
Dependencies (links to crates.io)
- clap: for parsing command-line arguments
- ureq: for performing the HTTP GET request to gmcmap.com
- serialport: for interfacing with the GMC's serial port via USB
Getting the data from the serial port
Content to come
main.rs (snippet)
fn main() {
<...>
match serialport::open_with_settings(&port_name, &SETTINGS) {
Ok(mut port) => {
let mut serial_buf: Vec<u8> = vec![0; 1000];
// Clear port by closing pending commands and reading the response
match port.write(">>".as_bytes()) {
Ok(size) if size == 2 => (),
Ok(_) => panic!("Sent wrong number of bytes!"),
Err(e) => panic!("{:?}", e),
}
// Give the device some time to respond
thread::sleep(Duration::from_millis(200));
// Clear serial IO buffers
match port.clear(ClearBuffer::All) {
Ok(_) => println!("Buffer cleared"),
Err(e) => panic!("Error clearing buffer! Message: {}", e),
}
// Request current CPM value from device
match port.write(b"<GETCPM>>") {
Ok(_) => println!("Getting current CPM..."),
Err(e) => panic!("{:?}", e),
}
// Force output before continuing the program (may be unnecessary)
match port.flush() {
_ => (),
}
// Give the device some time to respond
thread::sleep(Duration::from_millis(200));
// Check whether the response has correct length
match port.bytes_to_read() {
Ok(t) if t == 2 => (),
Ok(_) => panic!("Device's reponse doesn't have the correct length of 2!"),
Err(e) => panic!("{:?}", e),
}
let current_cpm: u16; // Counts Per Minute
let current_usvph: f32; // uSv/h
// Read the answer from the serial port
match port.read(serial_buf.as_mut_slice()) {
Ok(t) => println!("Result: size: {}, content: {:?}", t, &serial_buf[..t]),
Err(e) => panic!("{:?}", e),
}
// Combine the two u8 values into one u16 value
current_cpm = ((serial_buf[0] as u16) << 8) | serial_buf[1] as u16;
// Convert the CPM to uSv/h
current_usvph = (current_cpm as f32) * 6.5 / 1000.0;
println!("{} CPM, {} uSv/h", current_cpm, current_usvph);
match publish_result(&aid, &gid, ¤t_cpm, ¤t_usvph) {
Ok(_) => println!("Data successfully published"),
Err(e) => panic!("Publishing data failed! Error: '{}'", e),
}
}
Err(e) => {
panic!("Failed to open port {}. Error: {}", port_name, e);
}
}
}