{"id":1159,"date":"2012-03-23T15:20:56","date_gmt":"2012-03-23T19:20:56","guid":{"rendered":"http:\/\/lukemiller.org\/?p=1159"},"modified":"2015-10-07T09:31:21","modified_gmt":"2015-10-07T16:31:21","slug":"launching-ibutton-thermochrons-with-the-help-of-r","status":"publish","type":"post","link":"https:\/\/lukemiller.org\/index.php\/2012\/03\/launching-ibutton-thermochrons-with-the-help-of-r\/","title":{"rendered":"Launching iButton Thermochrons with the help of R"},"content":{"rendered":"<p>Maxim&#8217;s DS1921G <a href=\"http:\/\/www.maxim-ic.com\/products\/ibutton\/ibuttons\/thermochron.cfm\">iButton Thermochron<\/a> temperature dataloggers are little silver doo-dads the size of a large watch battery that can record up to 2048 time-stamped temperature values. The internal battery is usually good for a few years of use. Maxim supplies a Java-based application for talking to iButtons to start recording or to download results. This program, coupled with a <a href=\"http:\/\/www.maxim-ic.com\/products\/ibutton\/products\/1wire_adapters.cfm\">USB-based iButton adapter<\/a>, works fine when you&#8217;re just dealing with a few iButtons. But I have more than a few iButtons, so I used R to write a script to launch multiple iButtons quickly.<\/p>\n<figure id=\"attachment_1178\" aria-describedby=\"caption-attachment-1178\" style=\"width: 300px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/lukemiller.org\/wp-content\/uploads\/2012\/03\/ibutton-reader2.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-1178\" title=\"ibutton-reader2\" src=\"https:\/\/lukemiller.org\/wp-content\/uploads\/2012\/03\/ibutton-reader2-300x217.jpg\" alt=\"\" width=\"300\" height=\"217\" srcset=\"https:\/\/lukemiller.org\/wp-content\/uploads\/2012\/03\/ibutton-reader2-300x217.jpg 300w, https:\/\/lukemiller.org\/wp-content\/uploads\/2012\/03\/ibutton-reader2.jpg 500w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><figcaption id=\"caption-attachment-1178\" class=\"wp-caption-text\">An iButton (center) flanked by the DS9490B USB adapter and DS1402D-DR8 &#8220;blue-dot&#8221; iButton reader. Ignore the telephone wall jack in the upper left, that is just my solution for having bought the DS9490B instead of the DS9490R. You should buy the DS9490R.<\/figcaption><\/figure>\n<p>In my case, I want to launch 200-300 iButtons at a go, and I want them to all start recording at the same time. This would take hours using the Java applet, since you have to click your preferred settings for every new iButton, and you need to do the math on how long to delay the start so that the iButtons sync up. Fortunately, Maxim also makes a software development kit freely available for iButtons, and they also supply pre-compiled binary versions of the various utilities for talking to iButtons (i.e. command-line tools). Below I&#8217;ve written some R code to use one of these pre-compiled .exe&#8217;s to repeatedly launch many iButtons using identical mission parameters and equivalent starting times. R isn&#8217;t necessarily the best tool for this sort of thing, but it certainly works well enough.<\/p>\n<p>To start with, I used the USB drivers for my Windows 7 64-bit computer so it would talk to my DS9490B USB adapter for the iButtons. The instructions for getting this working are provided by Maxim Integrated here:<\/p>\n<p><a href=\"https:\/\/www.maximintegrated.com\/en\/app-notes\/index.mvp\/id\/4373\" target=\"_blank\">https:\/\/www.maximintegrated.com\/en\/app-notes\/index.mvp\/id\/4373<\/a><\/p>\n<p>and the link to download the actual drivers and OneWireViewer is here:<\/p>\n<p><a href=\"https:\/\/www.maximintegrated.com\/en\/products\/ibutton\/software\/tmex\/download_drivers.cfm\" target=\"_blank\">https:\/\/www.maximintegrated.com\/en\/products\/ibutton\/software\/tmex\/download_drivers.cfm<\/a><\/p>\n<p>After installing the drivers for the USB adapter, I ensured that it was working and could talk to iButtons using the Java OneWireViewer applet.<\/p>\n<p>Then I downloaded the 1-Wire Public Domain software development kit, in this case the pre-compiled binary version for Win64 USB Preliminary Version 3.11 Beta 2 that came as a zip file called\u00a0<strong>winusb64vc311Beta2_r2.zip<\/strong> (downloaded 2012-03-15).<\/p>\n<p><a href=\"http:\/\/www.maxim-ic.com\/products\/ibutton\/software\/1wire\/wirekit.cfm\">http:\/\/www.maxim-ic.com\/products\/ibutton\/software\/1wire\/wirekit.cfm<\/a><\/p>\n<p>There are several different potential versions of the kit listed on that page, and the only one that I have had success with thus far is the specific version named above. Scroll down near the bottom of that page to find the correct link, or use <a href=\"http:\/\/files.maximintegrated.com\/sia_bu\/public\/winusb64vc311Beta2_r2.zip\" target=\"_blank\">this direct link<\/a>. It works with the WinUSB drivers, while other versions that work with libusb haven&#8217;t given me any success. If you&#8217;re running 32-bit Windows, you might try the version winusb32vc311Beta2_r2.zip.<\/p>\n<p>Inside the winusb64vc311Beta2_r2.zip file, I found the necessary files thermoms.exe (for launching missions) and thermodl.exe (for downloading data, not covered here) in the \\builds\\winusb64vc\\release folder. I copied these two .exe&#8217;s to the directory that I use as my R working directory, so that I could call them from within my R script using the <code>system()<\/code> function. You probably don&#8217;t keep your code in D:\/R\/ibuttons, so you should ignore the <code>setwd(\"D:\/R\/ibuttons\")<\/code> call in the script below.<\/p>\n<p>The thermoms.exe program is called from within R using R&#8217;s <code>system()<\/code> function. This function takes a string as the first argument, and passes this string to the OS command line. In this case I send <code>thermoms.exe ds2490-0<\/code>, exactly as I would type it if I was using thermoms.exe at the Windows command line. The ds2490-0 instructs thermoms.exe to look for a ds2490 USB adapter on the system, and the -0 says to use the first one it finds (this should work for you if you only have one USB adapter). The answers to the questions that thermoms.exe usually asks are stored in the <code>mission.params<\/code> character vector and supplied as part of the <code>system()<\/code> call. This syntax will only work on Windows. Linux\/OSX will need different command line tools and syntax, and thus this script won&#8217;t work on Linux\/OSX. Versions of the scripts below can be downloaded from my <a href=\"https:\/\/github.com\/millerlp\/ibuttons\">GitHub repository<\/a>.<\/p>\n<div style=\"overflow: auto;\">\n<div class=\"geshifilter\">\n<pre class=\"r geshifilter-R\" style=\"font-family: monospace;\"><span style=\"color: #666666; font-style: italic;\"># The thermoms.exe program expects a series of inputs in order to establish the<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># mission parameters. Rgui doesn't work all that well with interactive command <\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># line programs (Rterm is just fine, but the goal is to not have to interact), <\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># so instead we'll create a character vector of answers to thermoms's <\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># queries and supply those via the input option of the system() function. <\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># The parameters are as follows:<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># Erase current mission (0) yes, (1) no. Answer: 0<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># Enter start delay in minutes (0 to 65535). Answer: whatever you choose<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># Enter sample rate in minutes (1 to 255). Answer: whatever you choose<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># Enable roll-over (0) yes, (1) no. Answer: 1<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># Enter high temperature threshold in Celsius (-40 to 70). Answer: 70<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># Enter low temperature threshold in Celsius (-40 to 70). Answer: -40<\/span>\r\n\r\nmission.params = <a href=\"http:\/\/inside-r.org\/r-doc\/base\/c\"><span style=\"color: #003399; font-weight: bold;\">c<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'0'<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #666666; font-style: italic;\"># erase current mission <\/span>\r\n\t\t<span style=\"color: #0000ff;\">'0'<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #666666; font-style: italic;\"># start delay in minutes (0 to 65535)<\/span>\r\n\t\t<span style=\"color: #0000ff;\">'255'<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #666666; font-style: italic;\"># sample rate in minutes (1 to 255)<\/span>\r\n\t\t<span style=\"color: #0000ff;\">'1'<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #666666; font-style: italic;\"># 0 = enable roll-over, 1 = no roll over<\/span>\r\n\t\t<span style=\"color: #0000ff;\">'70'<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #666666; font-style: italic;\"># high temperature threshold<\/span>\r\n\t\t<span style=\"color: #0000ff;\">'-40'<\/span><span style=\"color: #009900;\">)<\/span> <span style=\"color: #666666; font-style: italic;\"># low temperature threshold<\/span>\r\n\r\n<span style=\"color: #666666; font-style: italic;\"># Launch thermoms.exe<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># The 1st argument supplied to thermoms needs to be the location of the ibutton <\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># in the system. If using a DS9490B or DS9490R USB reader, you will probably get<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># away with using ds2490-0. The DS9490 uses a ds2490 chip internally, hence the <\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># given name.<\/span>\r\nout = <a href=\"http:\/\/inside-r.org\/r-doc\/base\/system\"><span style=\"color: #003399; font-weight: bold;\">system<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'thermoms.exe ds2490-0'<\/span><span style=\"color: #339933;\">,<\/span> intern = <span style=\"color: #000000; font-weight: bold;\">TRUE<\/span><span style=\"color: #339933;\">,<\/span> wait = <span style=\"color: #000000; font-weight: bold;\">TRUE<\/span><span style=\"color: #339933;\">,<\/span>\r\n\t\tinput = mission.params<span style=\"color: #009900;\">)<\/span>\r\n\r\n<span style=\"color: #666666; font-style: italic;\"># Display the output from the mission launch to show the user that launch was <\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># successful. <\/span>\r\n<span style=\"color: #000000; font-weight: bold;\">for<\/span> <span style=\"color: #009900;\">(<\/span>i <span style=\"color: #000000; font-weight: bold;\">in<\/span> <span style=\"color: #cc66cc;\">73<\/span>:<span style=\"color: #cc66cc;\">90<\/span><span style=\"color: #009900;\">)<\/span> <span style=\"color: #009900;\">{<\/span>\r\n\t<a href=\"http:\/\/inside-r.org\/r-doc\/base\/cat\"><span style=\"color: #003399; font-weight: bold;\">cat<\/span><\/a><span style=\"color: #009900;\">(<\/span>out<span style=\"color: #009900;\">[<\/span>i<span style=\"color: #009900;\">]<\/span><span style=\"color: #339933;\">,<\/span><span style=\"color: #0000ff;\">'<span style=\"color: #000099; font-weight: bold;\">\\n<\/span>'<\/span><span style=\"color: #009900;\">)<\/span>\r\n<span style=\"color: #009900;\">}<\/span>\r\n<a href=\"http:\/\/inside-r.org\/r-doc\/base\/cat\"><span style=\"color: #003399; font-weight: bold;\">cat<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'Finished<span style=\"color: #000099; font-weight: bold;\">\\a<\/span><span style=\"color: #000099; font-weight: bold;\">\\n<\/span>'<\/span><span style=\"color: #009900;\">)<\/span><\/pre>\n<\/div>\n<\/div>\n<p><a title=\"Created by Pretty R at inside-R.org\" href=\"http:\/\/www.inside-r.org\/pretty-r\">Created by Pretty R at inside-R.org<\/a><\/p>\n<p>The script above is extremely basic, and just launches one iButton when executed. In order to launch multiple iButtons, I wrote the version below <a href=\"https:\/\/github.com\/millerlp\/ibuttons\">(link to GitHub repository)<\/a> with a loop to send the same parameters to each new iButton that I plug in. The script below starts by asking the user for a time delay value, which can be up to 45.5 days in the future. The time delay must be entered as YYYY-mm-dd HH:MM, or the user can simply enter 0 to have the iButtons start recording immediately. If the user enters a non-zero time in the future, the script automatically adjusts the iButton start delay so that all iButtons will start at the user-specified time and date as time elapses while swapping iButtons in and out of the reader. The sampling frequency is also taken as an input, but all other mission parameters are hard-coded to my preferences.<\/p>\n<p>There are also some error-handling routines, since the mission doesn&#8217;t always upload correctly on the first try. The results of each mission launch are returned to R, and parsed to make sure they&#8217;re set as desired. The results are shown at the command line so the user can check them directly. If you want to launch another iButton, simply unplug the current iButton, plug in a new one to the reader, and then hit Enter to repeat the mission-launch loop. This process can be repeated endlessly until the user enters &#8220;q&#8221; and hits Enter to quit the script.<\/p>\n<div style=\"overflow: auto;\">\n<div class=\"geshifilter\">\n<pre class=\"r geshifilter-R\" style=\"font-family: monospace;\"><span style=\"color: #666666; font-style: italic;\"># Filename: mission_launch_multi.R<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># A script to upload new missions to iButton Thermochron temperature <\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># dataloggers. See the comments below for the additional external software <\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># needed to make this run. This version will loop continuously and upload the <\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># same mission to multiple iButtons so that they all start at the same <\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># absolute time and sample at the same frequency. <\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># Author: Luke Miller Mar 23, 2012<\/span>\r\n<span style=\"color: #666666; font-style: italic;\">###############################################################################<\/span>\r\n<a href=\"http:\/\/inside-r.org\/r-doc\/base\/setwd\"><span style=\"color: #003399; font-weight: bold;\">setwd<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'D:\/R\/ibuttons'<\/span><span style=\"color: #009900;\">)<\/span> <span style=\"color: #666666; font-style: italic;\"># Alter this for your needs, thermoms.exe must be in the<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># current R working directory.<\/span>\r\n\r\n<span style=\"color: #666666; font-style: italic;\"># The thermoms.exe file was originally downloaded as part of the Maxim iButton <\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># 1-Wire Public Domain Kit. <\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># There are several versions of the Kit available, including<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># versions with pre-compiled binaries (executables) for Windows\/Linux\/OSX.<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># http:\/\/www.maxim-ic.com\/products\/ibutton\/software\/1wire\/wirekit.cfm<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># On my Windows 7 x64 computer using the DS9490B USB ibutton adapter, I used the<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># precompiled binary build for Win64 USB (DS9490 + WinUSB) Preliminary Version <\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># 3.11 Beta 2,<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># filename: winusb64vc311Beta2_r2.zip, downloaded 2012-03-15<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># Unzip this file and find the .exe files thermoms.exe (and thermodl.exe) in the<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># builds\\winusb64vc\\release folder. Copy these to your R working directory.<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># The drivers for the DS9490 USB iButton adapter must also be downloaded and <\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># installed: <\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># http:\/\/www.maxim-ic.com\/products\/ibutton\/software\/tmex\/<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># I downloaded and installed the file \"install_1_wire_drivers_x64_v403.msi\"<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># The Java OneWireViewer app can also be downloaded and used to verify that your<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># drivers work and that you can communicate with iButtons successfully through <\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># the USB adapter. You can download this app here: <\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># http:\/\/www.maxim-ic.com\/products\/ibutton\/software\/1wire\/OneWireViewer.cfm<\/span>\r\n\r\n<a href=\"http:\/\/inside-r.org\/r-doc\/base\/cat\"><span style=\"color: #003399; font-weight: bold;\">cat<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'Enter a desired mission start time YYYY-MM-DD HH:MM<span style=\"color: #000099; font-weight: bold;\">\\n<\/span>'<\/span><span style=\"color: #009900;\">)<\/span>\r\n<a href=\"http:\/\/inside-r.org\/r-doc\/base\/cat\"><span style=\"color: #003399; font-weight: bold;\">cat<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'Enter 0 for immediate start. Delay must be less than 45.5 days.<span style=\"color: #000099; font-weight: bold;\">\\n<\/span>'<\/span><span style=\"color: #009900;\">)<\/span>\r\ntime.delay = <a href=\"http:\/\/inside-r.org\/r-doc\/base\/scan\"><span style=\"color: #003399; font-weight: bold;\">scan<\/span><\/a><span style=\"color: #009900;\">(<\/span><a href=\"http:\/\/inside-r.org\/r-doc\/base\/file\"><span style=\"color: #003399; font-weight: bold;\">file<\/span><\/a> = <span style=\"color: #0000ff;\">''<\/span><span style=\"color: #339933;\">,<\/span> what = <a href=\"http:\/\/inside-r.org\/r-doc\/base\/character\"><span style=\"color: #003399; font-weight: bold;\">character<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #009900;\">)<\/span><span style=\"color: #339933;\">,<\/span> n = <span style=\"color: #cc66cc;\">1<\/span><span style=\"color: #339933;\">,<\/span> sep = <span style=\"color: #0000ff;\">','<\/span><span style=\"color: #009900;\">)<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># The sep value in scan is necessary so that spaces are not interpreted as the<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># default record delimiter.<\/span>\r\n\r\n<span style=\"color: #000000; font-weight: bold;\">if<\/span> <span style=\"color: #009900;\">(<\/span>time.delay == <span style=\"color: #0000ff;\">'0'<\/span><span style=\"color: #009900;\">)<\/span> <span style=\"color: #009900;\">{<\/span>\r\n\tlaunch = <span style=\"color: #000000; font-weight: bold;\">TRUE<\/span>\r\n<span style=\"color: #009900;\">}<\/span> <span style=\"color: #000000; font-weight: bold;\">else<\/span> <span style=\"color: #009900;\">{<\/span>\r\n\t<span style=\"color: #666666; font-style: italic;\"># Convert the date\/time into a POSIX time object<\/span>\r\n\ttime.delay = <a href=\"http:\/\/inside-r.org\/r-doc\/base\/as.POSIXct\"><span style=\"color: #003399; font-weight: bold;\">as.POSIXct<\/span><\/a><span style=\"color: #009900;\">(<\/span>strptime<span style=\"color: #009900;\">(<\/span>time.delay<span style=\"color: #339933;\">,<\/span> <a href=\"http:\/\/inside-r.org\/r-doc\/base\/format\"><span style=\"color: #003399; font-weight: bold;\">format<\/span><\/a> = <span style=\"color: #0000ff;\">'%Y-%m-%d %H:%M'<\/span><span style=\"color: #009900;\">)<\/span><span style=\"color: #009900;\">)<\/span>\r\n\r\n\t<span style=\"color: #666666; font-style: italic;\"># Check to make sure that the delay time is usable<\/span>\r\n\t<span style=\"color: #000000; font-weight: bold;\">if<\/span> <span style=\"color: #009900;\">(<\/span><a href=\"http:\/\/inside-r.org\/r-doc\/base\/is.na\"><span style=\"color: #003399; font-weight: bold;\">is.na<\/span><\/a><span style=\"color: #009900;\">(<\/span>time.delay<span style=\"color: #009900;\">)<\/span><span style=\"color: #009900;\">)<\/span> <span style=\"color: #009900;\">{<\/span> <span style=\"color: #666666; font-style: italic;\"># If time.delay can't be interpreted, fail <\/span>\r\n\t\t<a href=\"http:\/\/inside-r.org\/r-doc\/base\/cat\"><span style=\"color: #003399; font-weight: bold;\">cat<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'Time could not be interpreted<span style=\"color: #000099; font-weight: bold;\">\\a<\/span><span style=\"color: #000099; font-weight: bold;\">\\n<\/span>'<\/span><span style=\"color: #009900;\">)<\/span>\r\n\t\t<a href=\"http:\/\/inside-r.org\/r-doc\/base\/cat\"><span style=\"color: #003399; font-weight: bold;\">cat<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'Quitting now<span style=\"color: #000099; font-weight: bold;\">\\n<\/span>'<\/span><span style=\"color: #009900;\">)<\/span>\r\n\t\tlaunch = <span style=\"color: #000000; font-weight: bold;\">FALSE<\/span>\r\n\t<span style=\"color: #009900;\">}<\/span>\r\n\t<span style=\"color: #666666; font-style: italic;\"># If time.delay is a valid POSIX time, check that it is within limits<\/span>\r\n\t<span style=\"color: #000000; font-weight: bold;\">if<\/span> <span style=\"color: #009900;\">(<\/span>!<a href=\"http:\/\/inside-r.org\/r-doc\/base\/is.na\"><span style=\"color: #003399; font-weight: bold;\">is.na<\/span><\/a><span style=\"color: #009900;\">(<\/span>time.delay<span style=\"color: #009900;\">)<\/span><span style=\"color: #009900;\">)<\/span> <span style=\"color: #009900;\">{<\/span>\r\n\t\tcurr.time = <a href=\"http:\/\/inside-r.org\/r-doc\/base\/as.POSIXct\"><span style=\"color: #003399; font-weight: bold;\">as.POSIXct<\/span><\/a><span style=\"color: #009900;\">(<\/span><a href=\"http:\/\/inside-r.org\/r-doc\/base\/Sys.time\"><span style=\"color: #003399; font-weight: bold;\">Sys.time<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #009900;\">)<\/span><span style=\"color: #009900;\">)<\/span> <span style=\"color: #666666; font-style: italic;\"># get current time<\/span>\r\n\t\t<span style=\"color: #666666; font-style: italic;\"># Check time difference between user's delay and current computer time<\/span>\r\n\t\tt.diff = <a href=\"http:\/\/inside-r.org\/r-doc\/base\/as.numeric\"><span style=\"color: #003399; font-weight: bold;\">as.numeric<\/span><\/a><span style=\"color: #009900;\">(<\/span>time.delay<span style=\"color: #009900;\">)<\/span> - <a href=\"http:\/\/inside-r.org\/r-doc\/base\/as.numeric\"><span style=\"color: #003399; font-weight: bold;\">as.numeric<\/span><\/a><span style=\"color: #009900;\">(<\/span>curr.time<span style=\"color: #009900;\">)<\/span>\r\n\t\tt.diff = t.diff \/ <span style=\"color: #cc66cc;\">60<\/span> <span style=\"color: #666666; font-style: italic;\"># convert to minutes<\/span>\r\n\r\n\t\t<span style=\"color: #000000; font-weight: bold;\">if<\/span> <span style=\"color: #009900;\">(<\/span>t.diff &lt; <span style=\"color: #cc66cc;\">0<\/span><span style=\"color: #009900;\">)<\/span> <span style=\"color: #009900;\">{<\/span>\r\n\t\t\t<a href=\"http:\/\/inside-r.org\/r-doc\/base\/cat\"><span style=\"color: #003399; font-weight: bold;\">cat<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'Time delay is less than zero. Check your watch.<span style=\"color: #000099; font-weight: bold;\">\\a<\/span><span style=\"color: #000099; font-weight: bold;\">\\n<\/span>'<\/span><span style=\"color: #009900;\">)<\/span>\r\n\t\t\t<a href=\"http:\/\/inside-r.org\/r-doc\/base\/cat\"><span style=\"color: #003399; font-weight: bold;\">cat<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'Quitting now<span style=\"color: #000099; font-weight: bold;\">\\n<\/span>'<\/span><span style=\"color: #009900;\">)<\/span>\r\n\t\t\tlaunch = <span style=\"color: #000000; font-weight: bold;\">FALSE<\/span>\r\n\t\t<span style=\"color: #009900;\">}<\/span> <span style=\"color: #000000; font-weight: bold;\">else<\/span> <span style=\"color: #000000; font-weight: bold;\">if<\/span> <span style=\"color: #009900;\">(<\/span>t.diff &gt; <span style=\"color: #cc66cc;\">65535<\/span><span style=\"color: #009900;\">)<\/span> <span style=\"color: #009900;\">{<\/span>\r\n\t\t\t<a href=\"http:\/\/inside-r.org\/r-doc\/base\/cat\"><span style=\"color: #003399; font-weight: bold;\">cat<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'Time delay is longer than 45.5 days. You are bad at math.<span style=\"color: #000099; font-weight: bold;\">\\a<\/span><span style=\"color: #000099; font-weight: bold;\">\\n<\/span>'<\/span><span style=\"color: #009900;\">)<\/span>\r\n\t\t\t<a href=\"http:\/\/inside-r.org\/r-doc\/base\/cat\"><span style=\"color: #003399; font-weight: bold;\">cat<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'Quitting now<span style=\"color: #000099; font-weight: bold;\">\\n<\/span>'<\/span><span style=\"color: #009900;\">)<\/span>\r\n\t\t\tlaunch = <span style=\"color: #000000; font-weight: bold;\">FALSE<\/span>\r\n\t\t<span style=\"color: #009900;\">}<\/span> <span style=\"color: #000000; font-weight: bold;\">else<\/span> <span style=\"color: #000000; font-weight: bold;\">if<\/span> <span style=\"color: #009900;\">(<\/span>t.diff &gt; <span style=\"color: #cc66cc;\">0<\/span> &amp; t.diff &lt; <span style=\"color: #cc66cc;\">1<\/span><span style=\"color: #009900;\">)<\/span> <span style=\"color: #009900;\">{<\/span>\r\n\t\t\t<a href=\"http:\/\/inside-r.org\/r-doc\/base\/cat\"><span style=\"color: #003399; font-weight: bold;\">cat<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'Time delay is being set to 0 for immediate launch.<span style=\"color: #000099; font-weight: bold;\">\\a<\/span><span style=\"color: #000099; font-weight: bold;\">\\n<\/span>'<\/span><span style=\"color: #009900;\">)<\/span>\r\n\t\t\tlaunch = <span style=\"color: #000000; font-weight: bold;\">TRUE<\/span>\r\n\t\t<span style=\"color: #009900;\">}<\/span> <span style=\"color: #000000; font-weight: bold;\">else<\/span> <span style=\"color: #009900;\">{<\/span>\r\n\t\t\t<span style=\"color: #666666; font-style: italic;\"># time.delay is a readable time, and t.diff is between 0 and 65535<\/span>\r\n\t\t\tlaunch = <span style=\"color: #000000; font-weight: bold;\">TRUE<\/span>\r\n\t\t<span style=\"color: #009900;\">}<\/span>\r\n\t<span style=\"color: #009900;\">}<\/span> <span style=\"color: #666666; font-style: italic;\"># end of !is.na(time.delay) if-statement<\/span>\r\n<span style=\"color: #009900;\">}<\/span> <span style=\"color: #666666; font-style: italic;\"># end of time.delay if-statement<\/span>\r\n\r\n<span style=\"color: #666666; font-style: italic;\">################################################################################<\/span>\r\n<span style=\"color: #666666; font-style: italic;\">## Start the launch loop. <\/span>\r\n\r\n<span style=\"color: #000000; font-weight: bold;\">if<\/span> <span style=\"color: #009900;\">(<\/span>launch<span style=\"color: #009900;\">)<\/span> <span style=\"color: #009900;\">{<\/span> <span style=\"color: #666666; font-style: italic;\">#only do this part if launch == TRUE<\/span>\r\n\t<a href=\"http:\/\/inside-r.org\/r-doc\/base\/cat\"><span style=\"color: #003399; font-weight: bold;\">cat<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'Enter the desired sampling frequency in minutes (1 to 255):<span style=\"color: #000099; font-weight: bold;\">\\n<\/span>'<\/span><span style=\"color: #009900;\">)<\/span>\r\n\tfreq = <a href=\"http:\/\/inside-r.org\/r-doc\/base\/scan\"><span style=\"color: #003399; font-weight: bold;\">scan<\/span><\/a><span style=\"color: #009900;\">(<\/span><a href=\"http:\/\/inside-r.org\/r-doc\/base\/file\"><span style=\"color: #003399; font-weight: bold;\">file<\/span><\/a> = <span style=\"color: #0000ff;\">''<\/span><span style=\"color: #339933;\">,<\/span> what = <a href=\"http:\/\/inside-r.org\/r-doc\/base\/numeric\"><span style=\"color: #003399; font-weight: bold;\">numeric<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #009900;\">)<\/span><span style=\"color: #339933;\">,<\/span> n = <span style=\"color: #cc66cc;\">1<\/span><span style=\"color: #009900;\">)<\/span>\r\n\tfreq = <a href=\"http:\/\/inside-r.org\/r-doc\/base\/as.character\"><span style=\"color: #003399; font-weight: bold;\">as.character<\/span><\/a><span style=\"color: #009900;\">(<\/span>freq<span style=\"color: #009900;\">)<\/span> <span style=\"color: #666666; font-style: italic;\"># convert to character<\/span>\r\n\tloop = <span style=\"color: #000000; font-weight: bold;\">TRUE<\/span> <span style=\"color: #666666; font-style: italic;\"># Set loop continuation variable to TRUE initially<\/span>\r\n\r\n\t<span style=\"color: #666666; font-style: italic;\"># This while loop will repeat continuously to launch multiple iButtons.<\/span>\r\n\t<span style=\"color: #666666; font-style: italic;\"># The same parameters will be used to launch every iButton, except that the <\/span>\r\n\t<span style=\"color: #666666; font-style: italic;\"># start delay (if &gt;0) will automatically adjust as time elapses so that each<\/span>\r\n\t<span style=\"color: #666666; font-style: italic;\"># iButton will start at the same absolute time. <\/span>\r\n\t<span style=\"color: #000000; font-weight: bold;\">while<\/span> <span style=\"color: #009900;\">(<\/span>loop<span style=\"color: #009900;\">)<\/span> <span style=\"color: #009900;\">{<\/span>\r\n\r\n\t\t<span style=\"color: #000000; font-weight: bold;\">if<\/span> <span style=\"color: #009900;\">(as.character(<\/span>time.delay) != <span style=\"color: #0000ff;\">'0'<\/span><span style=\"color: #009900;\">)<\/span> <span style=\"color: #009900;\">{<\/span>\r\n\t\t\tcurr.time = <a href=\"http:\/\/inside-r.org\/r-doc\/base\/as.POSIXct\"><span style=\"color: #003399; font-weight: bold;\">as.POSIXct<\/span><\/a><span style=\"color: #009900;\">(<\/span><a href=\"http:\/\/inside-r.org\/r-doc\/base\/Sys.time\"><span style=\"color: #003399; font-weight: bold;\">Sys.time<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #009900;\">)<\/span><span style=\"color: #009900;\">)<\/span> <span style=\"color: #666666; font-style: italic;\"># Get current time<\/span>\r\n\t\t\t<span style=\"color: #666666; font-style: italic;\"># Calculate difference between current time and time.delay value<\/span>\r\n\t\t\ttime.diff = <a href=\"http:\/\/inside-r.org\/r-doc\/base\/as.numeric\"><span style=\"color: #003399; font-weight: bold;\">as.numeric<\/span><\/a><span style=\"color: #009900;\">(<\/span>time.delay<span style=\"color: #009900;\">)<\/span> - <a href=\"http:\/\/inside-r.org\/r-doc\/base\/as.numeric\"><span style=\"color: #003399; font-weight: bold;\">as.numeric<\/span><\/a><span style=\"color: #009900;\">(<\/span>curr.time<span style=\"color: #009900;\">)<\/span>\r\n\t\t\ttime.diff = time.diff \/ <span style=\"color: #cc66cc;\">60<\/span> <span style=\"color: #666666; font-style: italic;\"># convert from seconds to minutes<\/span>\r\n\t\t\ttime.diff = <a href=\"http:\/\/inside-r.org\/r-doc\/base\/floor\"><span style=\"color: #003399; font-weight: bold;\">floor<\/span><\/a><span style=\"color: #009900;\">(<\/span>time.diff<span style=\"color: #009900;\">)<\/span> <span style=\"color: #666666; font-style: italic;\"># round down to nearest minute<\/span>\r\n\t\t\t<span style=\"color: #666666; font-style: italic;\"># iButtons only read out to the nearest minute. Rounding down to the<\/span>\r\n\t\t\t<span style=\"color: #666666; font-style: italic;\"># nearest minute should produce the proper delay to start at the <\/span>\r\n\t\t\t<span style=\"color: #666666; font-style: italic;\"># desired time. <\/span>\r\n\r\n\t\t\t<span style=\"color: #666666; font-style: italic;\"># If too much time elapses during this script, the time difference <\/span>\r\n\t\t\t<span style=\"color: #666666; font-style: italic;\"># could eventually shrink to zero or less than zero. In that case, <\/span>\r\n\t\t\t<span style=\"color: #666666; font-style: italic;\"># warn the user and set the iButton for immediate launch. <\/span>\r\n\t\t\t<span style=\"color: #000000; font-weight: bold;\">if<\/span> <span style=\"color: #009900;\">(<\/span>time.diff &lt; <span style=\"color: #cc66cc;\">1<\/span><span style=\"color: #009900;\">)<\/span> <span style=\"color: #009900;\">{<\/span>\r\n\t\t\t\ttime.diff = <span style=\"color: #cc66cc;\">0<\/span> <span style=\"color: #666666; font-style: italic;\"># set for immediate launch.<\/span>\r\n\t\t\t\t<a href=\"http:\/\/inside-r.org\/r-doc\/base\/cat\"><span style=\"color: #003399; font-weight: bold;\">cat<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'*********************************<span style=\"color: #000099; font-weight: bold;\">\\n<\/span>'<\/span><span style=\"color: #009900;\">)<\/span>\r\n\t\t\t\t<a href=\"http:\/\/inside-r.org\/r-doc\/base\/cat\"><span style=\"color: #003399; font-weight: bold;\">cat<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'Delay has shrunk to zero. Setting for immediate launch.'<\/span><span style=\"color: #009900;\">)<\/span>\r\n\t\t\t\t<a href=\"http:\/\/inside-r.org\/r-doc\/base\/cat\"><span style=\"color: #003399; font-weight: bold;\">cat<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'*********************************<span style=\"color: #000099; font-weight: bold;\">\\a<\/span><span style=\"color: #000099; font-weight: bold;\">\\n<\/span>'<\/span><span style=\"color: #009900;\">)<\/span>\r\n\t\t\t<span style=\"color: #009900;\">}<\/span>\r\n\t\t\ttime.diff = <a href=\"http:\/\/inside-r.org\/r-doc\/base\/as.character\"><span style=\"color: #003399; font-weight: bold;\">as.character<\/span><\/a><span style=\"color: #009900;\">(<\/span>time.diff<span style=\"color: #009900;\">)<\/span> <span style=\"color: #666666; font-style: italic;\"># convert to character <\/span>\r\n\t\t<span style=\"color: #009900;\">}<\/span> <span style=\"color: #000000; font-weight: bold;\">else<\/span> <span style=\"color: #009900;\">{<\/span> <span style=\"color: #666666; font-style: italic;\"># time.delay was originally set to 0, so keep that.<\/span>\r\n\t\t\ttime.diff == <span style=\"color: #0000ff;\">'0'<\/span>\r\n\t\t<span style=\"color: #009900;\">}<\/span>\r\n\t\t<a href=\"http:\/\/inside-r.org\/r-doc\/base\/cat\"><span style=\"color: #003399; font-weight: bold;\">cat<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'Calculated delay: '<\/span><span style=\"color: #339933;\">,<\/span> time.diff<span style=\"color: #339933;\">,<\/span> <span style=\"color: #0000ff;\">' minutes<span style=\"color: #000099; font-weight: bold;\">\\n<\/span>'<\/span><span style=\"color: #009900;\">)<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># The thermoms.exe program expects a series of inputs in order to establish the<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># mission parameters. Rgui doesn't work all that well with interactive command <\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># line programs (Rterm is just fine, but our goal is to not have to interact), <\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># so instead we'll create a character vector of answers to thermoms.exe's <\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># queries and supply those via the input option of the system() function. <\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># The parameters are as follows:<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># Erase current mission (0) yes, (1) no. Answer: 0<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># Enter start delay in minutes (0 to 65535). Answer: whatever you choose<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># Enter sample rate in minutes (1 to 255). Answer: whatever you choose<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># Enable roll-over (0) yes, (1) no. Answer: 1<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># Enter high temperature threshold in Celsius (-40 to 70). Answer: 70<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># Enter low temperature threshold in Celsius (-40 to 70). Answer: -40<\/span>\r\n\r\n\t\tmission.params = <a href=\"http:\/\/inside-r.org\/r-doc\/base\/c\"><span style=\"color: #003399; font-weight: bold;\">c<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'0'<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #666666; font-style: italic;\"># erase current mission <\/span>\r\n\t\t\t\ttime.diff<span style=\"color: #339933;\">,<\/span> <span style=\"color: #666666; font-style: italic;\"># start delay in minutes (0 to 65535)<\/span>\r\n\t\t\t\tfreq<span style=\"color: #339933;\">,<\/span> <span style=\"color: #666666; font-style: italic;\"># sample rate in minutes (1 to 255)<\/span>\r\n\t\t\t\t<span style=\"color: #0000ff;\">'1'<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #666666; font-style: italic;\"># enable roll-over? 1 = no roll over<\/span>\r\n\t\t\t\t<span style=\"color: #0000ff;\">'70'<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #666666; font-style: italic;\"># high temperature threshold<\/span>\r\n\t\t\t\t<span style=\"color: #0000ff;\">'-40'<\/span><span style=\"color: #009900;\">)<\/span> <span style=\"color: #666666; font-style: italic;\"># low temperature threshold<\/span>\r\n\r\n<span style=\"color: #666666; font-style: italic;\"># Launch thermoms.exe<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># The 1st argument supplied to thermoms needs to be the location of the iButton <\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># in the system. If using a DS9490B USB reader on Windows, you will probably get <\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># away with using ds2490-0. The DS9490 USB reader uses a ds2490 chip internally, <\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># so you need to tell thermoms.exe to look for a ds2490. <\/span>\r\n\t\tout = <a href=\"http:\/\/inside-r.org\/r-doc\/base\/system\"><span style=\"color: #003399; font-weight: bold;\">system<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'thermoms.exe ds2490-0'<\/span><span style=\"color: #339933;\">,<\/span> intern = <span style=\"color: #000000; font-weight: bold;\">TRUE<\/span><span style=\"color: #339933;\">,<\/span> wait = <span style=\"color: #000000; font-weight: bold;\">TRUE<\/span><span style=\"color: #339933;\">,<\/span>\r\n\t\t\t\tinput = mission.params<span style=\"color: #009900;\">)<\/span>\r\n\r\n<span style=\"color: #666666; font-style: italic;\"># Check the output from the mission launch to ensure that the correct parameters<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># were registered. Occasionally the time delay will not be properly registered <\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># on the first launch, so the loops below will immediately relaunch the mission<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># to get the time delay to register properly.<\/span>\r\n\r\n\t\t<span style=\"color: #666666; font-style: italic;\"># If no iButton is plugged in, this should be the failure message<\/span>\r\n\t\t<span style=\"color: #000000; font-weight: bold;\">if<\/span> <span style=\"color: #009900;\">(<\/span>out<span style=\"color: #009900;\">[<\/span><span style=\"color: #cc66cc;\">7<\/span><span style=\"color: #009900;\">]<\/span> == <span style=\"color: #0000ff;\">'Thermochron not present on 1-Wire'<\/span><span style=\"color: #009900;\">)<\/span> <span style=\"color: #009900;\">{<\/span>\r\n\t\t\t<a href=\"http:\/\/inside-r.org\/r-doc\/base\/cat\"><span style=\"color: #003399; font-weight: bold;\">cat<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'******************************************<span style=\"color: #000099; font-weight: bold;\">\\n<\/span>'<\/span><span style=\"color: #009900;\">)<\/span>\r\n\t\t\t<a href=\"http:\/\/inside-r.org\/r-doc\/base\/cat\"><span style=\"color: #003399; font-weight: bold;\">cat<\/span><\/a><span style=\"color: #009900;\">(<\/span>out<span style=\"color: #009900;\">[<\/span><span style=\"color: #cc66cc;\">7<\/span><span style=\"color: #009900;\">]<\/span><span style=\"color: #339933;\">,<\/span><span style=\"color: #0000ff;\">'<span style=\"color: #000099; font-weight: bold;\">\\n<\/span>'<\/span><span style=\"color: #009900;\">)<\/span>\r\n\t\t\t<a href=\"http:\/\/inside-r.org\/r-doc\/base\/cat\"><span style=\"color: #003399; font-weight: bold;\">cat<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'******************************************<span style=\"color: #000099; font-weight: bold;\">\\n<\/span><span style=\"color: #000099; font-weight: bold;\">\\a<\/span>'<\/span><span style=\"color: #009900;\">)<\/span>\r\n\t\t<span style=\"color: #009900;\">}<\/span> <span style=\"color: #000000; font-weight: bold;\">else<\/span> <span style=\"color: #009900;\">{<\/span> <span style=\"color: #666666; font-style: italic;\"># if out[7] is blank, a mission was probably uploaded<\/span>\r\n\t\t\t<span style=\"color: #000000; font-weight: bold;\">for<\/span> <span style=\"color: #009900;\">(<\/span>i <span style=\"color: #000000; font-weight: bold;\">in<\/span> <span style=\"color: #cc66cc;\">73<\/span>:<span style=\"color: #cc66cc;\">90<\/span><span style=\"color: #009900;\">)<\/span> <span style=\"color: #009900;\">{<\/span> <span style=\"color: #666666; font-style: italic;\"># Display read-back from mission upload<\/span>\r\n\t\t\t\t<a href=\"http:\/\/inside-r.org\/r-doc\/base\/cat\"><span style=\"color: #003399; font-weight: bold;\">cat<\/span><\/a><span style=\"color: #009900;\">(<\/span>out<span style=\"color: #009900;\">[<\/span>i<span style=\"color: #009900;\">]<\/span><span style=\"color: #339933;\">,<\/span><span style=\"color: #0000ff;\">'<span style=\"color: #000099; font-weight: bold;\">\\n<\/span>'<\/span><span style=\"color: #009900;\">)<\/span>\r\n\t\t\t<span style=\"color: #009900;\">}<\/span>\r\n\r\n\t\t\t<span style=\"color: #666666; font-style: italic;\"># Make sure the delay was actually entered correctly if it's &gt;0<\/span>\r\n\t\t\t<span style=\"color: #666666; font-style: italic;\"># This while loop will run a maximum of 3 times. Each time through <\/span>\r\n\t\t\t<span style=\"color: #666666; font-style: italic;\"># it will compare the output in out[73] to make sure the correct <\/span>\r\n\t\t\t<span style=\"color: #666666; font-style: italic;\"># delay was returned from the iButton. If not, it will re-launch the<\/span>\r\n\t\t\t<span style=\"color: #666666; font-style: italic;\"># mission up to two more times before sending a failure message<\/span>\r\n\t\t\tretry = <span style=\"color: #cc66cc;\">0<\/span>\r\n\t\t\t<span style=\"color: #000000; font-weight: bold;\">while<\/span> <span style=\"color: #009900;\">(<\/span>retry &lt; <span style=\"color: #cc66cc;\">3<\/span><span style=\"color: #009900;\">)<\/span> <span style=\"color: #009900;\">{<\/span>\r\n\t\t\t\tsetting = out<span style=\"color: #009900;\">[<\/span><span style=\"color: #cc66cc;\">79<\/span><span style=\"color: #009900;\">]<\/span>\r\n\t\t\t\tnums = <a href=\"http:\/\/inside-r.org\/r-doc\/base\/gregexpr\"><span style=\"color: #003399; font-weight: bold;\">gregexpr<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'[0-9]'<\/span><span style=\"color: #339933;\">,<\/span> setting<span style=\"color: #009900;\">)<\/span> <span style=\"color: #666666; font-style: italic;\"># Find numbers in the string<\/span>\r\n\t\t\t\tdigs = <a href=\"http:\/\/inside-r.org\/r-doc\/base\/substr\"><span style=\"color: #003399; font-weight: bold;\">substr<\/span><\/a><span style=\"color: #009900;\">(<\/span>setting<span style=\"color: #339933;\">,<\/span> nums<span style=\"color: #009900;\">[<\/span><span style=\"color: #009900;\">[<\/span><span style=\"color: #cc66cc;\">1<\/span><span style=\"color: #009900;\">]<\/span><span style=\"color: #009900;\">]<\/span><span style=\"color: #009900;\">[<\/span><span style=\"color: #cc66cc;\">1<\/span><span style=\"color: #009900;\">]<\/span><span style=\"color: #339933;\">,<\/span>\r\n\t\t\t\t\t\tnums<span style=\"color: #009900;\">[<\/span><span style=\"color: #009900;\">[<\/span><span style=\"color: #cc66cc;\">1<\/span><span style=\"color: #009900;\">]<\/span><span style=\"color: #009900;\">]<\/span><span style=\"color: #009900;\">[<\/span><a href=\"http:\/\/inside-r.org\/r-doc\/base\/length\"><span style=\"color: #003399; font-weight: bold;\">length<\/span><\/a><span style=\"color: #009900;\">(<\/span>nums<span style=\"color: #009900;\">[<\/span><span style=\"color: #009900;\">[<\/span><span style=\"color: #cc66cc;\">1<\/span><span style=\"color: #009900;\">]<\/span><span style=\"color: #009900;\">]<\/span><span style=\"color: #009900;\">)<\/span><span style=\"color: #009900;\">]<\/span><span style=\"color: #009900;\">)<\/span> <span style=\"color: #666666; font-style: italic;\"># Extract delay value<\/span>\r\n\t\t\t\t<span style=\"color: #000000; font-weight: bold;\">if<\/span> <span style=\"color: #009900;\">(<\/span>digs != time.diff &amp; retry &lt; <span style=\"color: #cc66cc;\">2<\/span><span style=\"color: #009900;\">)<\/span> <span style=\"color: #009900;\">{<\/span>\r\n\t\t\t\t\t<span style=\"color: #666666; font-style: italic;\"># If delay value returned by iButton doesn't match the <\/span>\r\n\t\t\t\t\t<span style=\"color: #666666; font-style: italic;\"># programmed delay, warn the user and re-launch the mission<\/span>\r\n\t\t\t\t\t<a href=\"http:\/\/inside-r.org\/r-doc\/base\/cat\"><span style=\"color: #003399; font-weight: bold;\">cat<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'*****************************************<span style=\"color: #000099; font-weight: bold;\">\\n<\/span>'<\/span><span style=\"color: #009900;\">)<\/span>\r\n\t\t\t\t\t<a href=\"http:\/\/inside-r.org\/r-doc\/base\/cat\"><span style=\"color: #003399; font-weight: bold;\">cat<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'****Launch did not work, re-launching****<span style=\"color: #000099; font-weight: bold;\">\\a<\/span><span style=\"color: #000099; font-weight: bold;\">\\n<\/span>'<\/span><span style=\"color: #009900;\">)<\/span>\r\n\t\t\t\t\t<a href=\"http:\/\/inside-r.org\/r-doc\/base\/cat\"><span style=\"color: #003399; font-weight: bold;\">cat<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'*****************************************<span style=\"color: #000099; font-weight: bold;\">\\n<\/span>'<\/span><span style=\"color: #009900;\">)<\/span>\r\n\t\t\t\t\tout = <a href=\"http:\/\/inside-r.org\/r-doc\/base\/system\"><span style=\"color: #003399; font-weight: bold;\">system<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'thermoms.exe ds2490-0'<\/span><span style=\"color: #339933;\">,<\/span> intern = <span style=\"color: #000000; font-weight: bold;\">TRUE<\/span><span style=\"color: #339933;\">,<\/span>\r\n\t\t\t\t\t\t\twait = <span style=\"color: #000000; font-weight: bold;\">TRUE<\/span><span style=\"color: #339933;\">,<\/span> input = mission.params<span style=\"color: #009900;\">)<\/span>\r\n\t\t\t\t\t<span style=\"color: #000000; font-weight: bold;\">for<\/span> <span style=\"color: #009900;\">(<\/span>i <span style=\"color: #000000; font-weight: bold;\">in<\/span> <span style=\"color: #cc66cc;\">73<\/span>:<span style=\"color: #cc66cc;\">90<\/span><span style=\"color: #009900;\">)<\/span> <span style=\"color: #009900;\">{<\/span> <span style=\"color: #666666; font-style: italic;\"># Display the newly returned values<\/span>\r\n\t\t\t\t\t\t<a href=\"http:\/\/inside-r.org\/r-doc\/base\/cat\"><span style=\"color: #003399; font-weight: bold;\">cat<\/span><\/a><span style=\"color: #009900;\">(<\/span>out<span style=\"color: #009900;\">[<\/span>i<span style=\"color: #009900;\">]<\/span><span style=\"color: #339933;\">,<\/span><span style=\"color: #0000ff;\">'<span style=\"color: #000099; font-weight: bold;\">\\n<\/span>'<\/span><span style=\"color: #009900;\">)<\/span>\r\n\t\t\t\t\t<span style=\"color: #009900;\">}<\/span>\r\n\t\t\t\t\tretry = retry + <span style=\"color: #cc66cc;\">1<\/span> <span style=\"color: #666666; font-style: italic;\"># increment the loop counter<\/span>\r\n\t\t\t\t\t<a href=\"http:\/\/inside-r.org\/r-doc\/base\/cat\"><span style=\"color: #003399; font-weight: bold;\">cat<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'---------------------------<span style=\"color: #000099; font-weight: bold;\">\\n<\/span>'<\/span><span style=\"color: #009900;\">)<\/span>\r\n\t\t\t\t<span style=\"color: #009900;\">}<\/span> <span style=\"color: #000000; font-weight: bold;\">else<\/span> <span style=\"color: #000000; font-weight: bold;\">if<\/span> <span style=\"color: #009900;\">(<\/span>digs != time.diff &amp; retry == <span style=\"color: #cc66cc;\">2<\/span><span style=\"color: #009900;\">)<\/span> <span style=\"color: #009900;\">{<\/span>\r\n\t\t\t\t\t<span style=\"color: #666666; font-style: italic;\"># If the returned delay still doesn't match the programmed<\/span>\r\n\t\t\t\t\t<span style=\"color: #666666; font-style: italic;\"># delay after two more iterations, send a failure message<\/span>\r\n\t\t\t\t\t<span style=\"color: #666666; font-style: italic;\"># to the user and let them deal with this issue. <\/span>\r\n\t\t\t\t\t<span style=\"color: #666666; font-style: italic;\"># A common failure mode is due to a dead battery, which will<\/span>\r\n\t\t\t\t\t<span style=\"color: #666666; font-style: italic;\"># keep returning a clock time of 01\/01\/1970 00:00:00<\/span>\r\n\t\t\t\t\tretry = <span style=\"color: #cc66cc;\">3<\/span>\r\n\t\t\t\t\t<a href=\"http:\/\/inside-r.org\/r-doc\/base\/cat\"><span style=\"color: #003399; font-weight: bold;\">cat<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'****************************************<span style=\"color: #000099; font-weight: bold;\">\\n<\/span>'<\/span><span style=\"color: #009900;\">)<\/span>\r\n\t\t\t\t\t<a href=\"http:\/\/inside-r.org\/r-doc\/base\/cat\"><span style=\"color: #003399; font-weight: bold;\">cat<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'*****Uploaded failed, check iButton*****<span style=\"color: #000099; font-weight: bold;\">\\n<\/span>'<\/span><span style=\"color: #009900;\">)<\/span>\r\n\t\t\t\t\t<a href=\"http:\/\/inside-r.org\/r-doc\/base\/cat\"><span style=\"color: #003399; font-weight: bold;\">cat<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'****************************************<span style=\"color: #000099; font-weight: bold;\">\\n<\/span>'<\/span><span style=\"color: #009900;\">)<\/span>\r\n\t\t\t\t\t<span style=\"color: #000000; font-weight: bold;\">for<\/span> <span style=\"color: #009900;\">(<\/span>i <span style=\"color: #000000; font-weight: bold;\">in<\/span> <span style=\"color: #cc66cc;\">73<\/span>:<span style=\"color: #cc66cc;\">90<\/span><span style=\"color: #009900;\">)<\/span> <span style=\"color: #009900;\">{<\/span>\r\n\t\t\t\t\t\t<a href=\"http:\/\/inside-r.org\/r-doc\/base\/cat\"><span style=\"color: #003399; font-weight: bold;\">cat<\/span><\/a><span style=\"color: #009900;\">(<\/span>out<span style=\"color: #009900;\">[<\/span>i<span style=\"color: #009900;\">]<\/span><span style=\"color: #339933;\">,<\/span><span style=\"color: #0000ff;\">'<span style=\"color: #000099; font-weight: bold;\">\\n<\/span>'<\/span><span style=\"color: #009900;\">)<\/span>\r\n\t\t\t\t\t<span style=\"color: #009900;\">}<\/span>\r\n\r\n\t\t\t\t\tanswer = out<span style=\"color: #009900;\">[<\/span><span style=\"color: #cc66cc;\">85<\/span><span style=\"color: #009900;\">]<\/span> <span style=\"color: #666666; font-style: italic;\"># Check the iButton's internal clock<\/span>\r\n\r\n\t\t\t\t\t<span style=\"color: #666666; font-style: italic;\"># Find the location of the date in this line (if present)<\/span>\r\n\t\t\t\t\td1 = <a href=\"http:\/\/inside-r.org\/r-doc\/base\/regexpr\"><span style=\"color: #003399; font-weight: bold;\">regexpr<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'[0-9]{2}\/[0-9]{2}\/[0-9]{4}'<\/span><span style=\"color: #339933;\">,<\/span> answer<span style=\"color: #009900;\">)<\/span>\r\n\r\n\t\t\t\t\t<span style=\"color: #666666; font-style: italic;\"># Extract the date as a character string<\/span>\r\n\t\t\t\t\tbutton.date = <a href=\"http:\/\/inside-r.org\/r-doc\/base\/substr\"><span style=\"color: #003399; font-weight: bold;\">substr<\/span><\/a><span style=\"color: #009900;\">(<\/span>answer<span style=\"color: #339933;\">,<\/span> d1<span style=\"color: #339933;\">,<\/span>\r\n\t\t\t\t\t\t\td1 + <a href=\"http:\/\/inside-r.org\/r-doc\/base\/attr\"><span style=\"color: #003399; font-weight: bold;\">attr<\/span><\/a><span style=\"color: #009900;\">(<\/span>d1<span style=\"color: #339933;\">,<\/span><span style=\"color: #0000ff;\">'match.length'<\/span><span style=\"color: #009900;\">)<\/span> - <span style=\"color: #cc66cc;\">1<\/span><span style=\"color: #009900;\">)<\/span>\r\n\r\n\t\t\t\t\t<span style=\"color: #666666; font-style: italic;\"># If the iButton date returns 01\/01\/1970, the iButton <\/span>\r\n\t\t\t\t\t<span style=\"color: #666666; font-style: italic;\"># battery is probably dead<\/span>\r\n\t\t\t\t\t<span style=\"color: #000000; font-weight: bold;\">if<\/span> <span style=\"color: #009900;\">(<\/span>button.date == <span style=\"color: #0000ff;\">'01\/01\/1970'<\/span><span style=\"color: #009900;\">)<\/span> <span style=\"color: #009900;\">{<\/span>\r\n\t\t\t\t\t\t<a href=\"http:\/\/inside-r.org\/r-doc\/base\/cat\"><span style=\"color: #003399; font-weight: bold;\">cat<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'********************************<span style=\"color: #000099; font-weight: bold;\">\\n<\/span>'<\/span><span style=\"color: #009900;\">)<\/span>\r\n\t\t\t\t\t\t<a href=\"http:\/\/inside-r.org\/r-doc\/base\/cat\"><span style=\"color: #003399; font-weight: bold;\">cat<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'The iButton battery may be dead.<span style=\"color: #000099; font-weight: bold;\">\\n<\/span>'<\/span><span style=\"color: #009900;\">)<\/span>\r\n\t\t\t\t\t\t<a href=\"http:\/\/inside-r.org\/r-doc\/base\/cat\"><span style=\"color: #003399; font-weight: bold;\">cat<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'********************************<span style=\"color: #000099; font-weight: bold;\">\\n<\/span>'<\/span><span style=\"color: #009900;\">)<\/span>\r\n\t\t\t\t\t<span style=\"color: #009900;\">}<\/span>\r\n\r\n\t\t\t\t<span style=\"color: #009900;\">}<\/span> <span style=\"color: #000000; font-weight: bold;\">else<\/span> <span style=\"color: #000000; font-weight: bold;\">if<\/span> <span style=\"color: #009900;\">(<\/span>digs == time.diff<span style=\"color: #009900;\">)<\/span> <span style=\"color: #009900;\">{<\/span> <span style=\"color: #666666; font-style: italic;\"># iButton mission launch worked<\/span>\r\n\t\t\t\t\t<a href=\"http:\/\/inside-r.org\/r-doc\/base\/cat\"><span style=\"color: #003399; font-weight: bold;\">cat<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'<span style=\"color: #000099; font-weight: bold;\">\\n<\/span>----------Success---------<span style=\"color: #000099; font-weight: bold;\">\\n<\/span>'<\/span><span style=\"color: #009900;\">)<\/span>\r\n\t\t\t\t\tretry = <span style=\"color: #cc66cc;\">3<\/span>\r\n\t\t\t\t<span style=\"color: #009900;\">}<\/span>\r\n\t\t\t<span style=\"color: #009900;\">}<\/span> <span style=\"color: #666666; font-style: italic;\"># End of retry while-loop<\/span>\r\n\t\t<span style=\"color: #009900;\">}<\/span> <span style=\"color: #666666; font-style: italic;\"># End of if (out[7]... if-else statements<\/span>\r\n\r\n\t\t<span style=\"color: #666666; font-style: italic;\"># Ask the user to load the next iButton or quit.<\/span>\r\n\t\t<a href=\"http:\/\/inside-r.org\/r-doc\/base\/cat\"><span style=\"color: #003399; font-weight: bold;\">cat<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'Swap next iButton and press Enter to launch. Enter q to quit.<span style=\"color: #000099; font-weight: bold;\">\\a<\/span><span style=\"color: #000099; font-weight: bold;\">\\n<\/span>'<\/span><span style=\"color: #009900;\">)<\/span>\r\n\t\tuser.input = <a href=\"http:\/\/inside-r.org\/r-doc\/base\/scan\"><span style=\"color: #003399; font-weight: bold;\">scan<\/span><\/a><span style=\"color: #009900;\">(<\/span><a href=\"http:\/\/inside-r.org\/r-doc\/base\/file\"><span style=\"color: #003399; font-weight: bold;\">file<\/span><\/a> = <span style=\"color: #0000ff;\">''<\/span><span style=\"color: #339933;\">,<\/span> what = <a href=\"http:\/\/inside-r.org\/r-doc\/base\/character\"><span style=\"color: #003399; font-weight: bold;\">character<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #009900;\">)<\/span><span style=\"color: #339933;\">,<\/span> n = <span style=\"color: #cc66cc;\">1<\/span><span style=\"color: #009900;\">)<\/span>\r\n\t\t<span style=\"color: #000000; font-weight: bold;\">if<\/span> <span style=\"color: #009900;\">(<\/span><a href=\"http:\/\/inside-r.org\/r-doc\/base\/length\"><span style=\"color: #003399; font-weight: bold;\">length<\/span><\/a><span style=\"color: #009900;\">(<\/span>user.input<span style=\"color: #009900;\">)<\/span> &gt; <span style=\"color: #cc66cc;\">0<\/span><span style=\"color: #009900;\">)<\/span> <span style=\"color: #009900;\">{<\/span> <span style=\"color: #666666; font-style: italic;\"># Allows user to not type anything<\/span>\r\n\t\t\t<span style=\"color: #000000; font-weight: bold;\">if<\/span> <span style=\"color: #009900;\">(<\/span>user.input == <span style=\"color: #0000ff;\">'q'<\/span><span style=\"color: #009900;\">)<\/span> loop = <span style=\"color: #000000; font-weight: bold;\">FALSE<\/span> <span style=\"color: #666666; font-style: italic;\"># Kills loop<\/span>\r\n\t\t<span style=\"color: #009900;\">}<\/span> <span style=\"color: #000000; font-weight: bold;\">else<\/span> <span style=\"color: #009900;\">{<\/span>loop = <span style=\"color: #000000; font-weight: bold;\">TRUE<\/span><span style=\"color: #009900;\">}<\/span>\r\n\t<span style=\"color: #009900;\">}<\/span> <span style=\"color: #666666; font-style: italic;\"># End of 'loop' while-loop<\/span>\r\n<span style=\"color: #009900;\">}<\/span> <span style=\"color: #666666; font-style: italic;\"># End of 'launch' if-statement<\/span>\r\n\r\n<a href=\"http:\/\/inside-r.org\/r-doc\/base\/cat\"><span style=\"color: #003399; font-weight: bold;\">cat<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'Finished <span style=\"color: #000099; font-weight: bold;\">\\a<\/span><span style=\"color: #000099; font-weight: bold;\">\\n<\/span>'<\/span><span style=\"color: #009900;\">)<\/span><\/pre>\n<\/div>\n<\/div>\n<p><a title=\"Created by Pretty R at inside-R.org\" href=\"http:\/\/www.inside-r.org\/pretty-r\">Created by Pretty R at inside-R.org<\/a><\/p>\n<p>The output from a typical launch cycle looks like the following:<\/p>\n<pre>Calculated delay:  42  minutes\r\nSerial Number of DS1921: 4B0000002D1FCB21\r\nMission is in progress\r\nSample rate: 5 minute(s)\r\nRoll-Over Enabled: no\r\nRoll-Over Occurred: no\r\nMission Start time: na\r\nMission Start delay: 42 minute(s)\r\nMission Samples: 0\r\nDevice total samples: 1990\r\nTemp displayed in: (Celsius)\r\nHigh Threshold:   70.0\r\nLow Threshold:  -40.0\r\nCurrent Real-Time Clock from DS1921: 03\/23\/2012  11:47:52\r\nCurrent PC Time: 03\/23\/2012  11:47:51 \r\n\r\nClosing port DS2490-0.\r\nEnd program normally\r\n\/\/\/\/\/\/\/Success\/\/\/\/\/\/\/\r\nSwap next iButton and press Enter to launch. Enter q to quit.\r\n1:<\/pre>\n<p>The upshot of all of this is that I can now launch about 300 iButtons in roughly 20 minutes, and the limiting factor is how fast I can pop the buttons in and out of the reader (the repetitive stress injuries I&#8217;ll surely incur will slow things down). This script only handles launching a single iButton at a time. The blue-dot reader can hold two iButtons, and thermoms.exe will launch both simultaneously, but this script only looks at the results from the first iButton, so it could miss errors on the second iButton.<\/p>\n<p>&nbsp;<\/p>\n<p>Updated 2015-10-07 with new working links to Maxim.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Maxim&#8217;s iButton Thermochron temperature dataloggers are little silver doo-dads the size of a large watch battery that can record up to 2048 time-stamped temperature values. The internal battery is usually good for a few years of use. Maxim supplies a Java-based application for talking to iButtons to start recording or to download results. This program, coupled with a USB-based iButton adapter, works fine when you&#8217;re just dealing with a few iButtons. But I have more than a few iButtons, so I used R to write a script to launch multiple iButtons quickly. <\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[218],"tags":[129,127,128,125,126,130],"class_list":["post-1159","post","type-post","status-publish","format-standard","hentry","category-r-project","tag-ds1921g","tag-ds9490b","tag-ds9490r","tag-ibutton","tag-system","tag-thermochron"],"_links":{"self":[{"href":"https:\/\/lukemiller.org\/index.php\/wp-json\/wp\/v2\/posts\/1159","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lukemiller.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lukemiller.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lukemiller.org\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/lukemiller.org\/index.php\/wp-json\/wp\/v2\/comments?post=1159"}],"version-history":[{"count":26,"href":"https:\/\/lukemiller.org\/index.php\/wp-json\/wp\/v2\/posts\/1159\/revisions"}],"predecessor-version":[{"id":2107,"href":"https:\/\/lukemiller.org\/index.php\/wp-json\/wp\/v2\/posts\/1159\/revisions\/2107"}],"wp:attachment":[{"href":"https:\/\/lukemiller.org\/index.php\/wp-json\/wp\/v2\/media?parent=1159"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lukemiller.org\/index.php\/wp-json\/wp\/v2\/categories?post=1159"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lukemiller.org\/index.php\/wp-json\/wp\/v2\/tags?post=1159"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}