Reading Arduino data directly into R

[This article was first published on mages' blog, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

I have experimented with reading an Arduino signal into R in the past, using Rserve and Processing. Actually, it is much easier. I can read the output of my Arduino directly into R with the scan function.

Here is my temperature sensor example again:


And all it needs to read the signal into the R console with my computer is:
> f <- file("/dev/cu.usbmodem3a21", open="r")
> scan(f, n=1)
Read 1 item
[1] 20.8
> close(f)
Super simple: Open the file connection. Scan n lines of data. Close the file connection. Job done.

Note: This worked for me on my Mac and I am sure it will work in a very similar way on a Linux box as well, but I am not so sure about Windows. Crucially, I had to learn the difference between the tty* and cu* devices. I found the following statement in Mike’s PBX Cookbook particular insightful:
You might notice that each serial device shows up twice in /dev, once as a tty.* and once as a cu.*. So, what’s the difference? Well, TTY devices are for calling into UNIX systems, whereas CU (Call-Up) devices are for calling out from them (eg, modems). We want to call-out from our Mac, so /dev/cu.* is the correct device to use.
You find the file address of your Arduino by opening the Arduino software and looking it up under the menu Tools > Port.

With a little more R code I can create a ‘live’ data stream plot of my Arduino.

Reload this page to see the animated Gif again.

R code
f <- file("/dev/cu.usbmodem3a21", open="r")
nObs <- 50
Temperature <- rep(NA, nObs)
cycle <- 0
while(cycle<10){
time <- ((cycle*nObs):((cycle+1)*(nObs)))[-1]
plot(Temperature ~ time, t="n", ylim=c(18, 24),
main="Data stream from Arduino via USB port")
for(i in 1:nObs){
Temperature[i] <- scan(f, n=1, quiet=TRUE)
points(i + cycle*nObs, Temperature[i], pch=19)
Sys.sleep(0.05)
}
cycle <- cycle + 1
}
close(f)

Here is the original Arduino sketch as well:
// TMP36 Pin Variables
// the analog pin the TMP36's Vout (sense) pin is connected to
// the resolution is 10 mV / degree centigrade with a
// 500 mV offset to allow for negative temperatures
int sensorPin = 0;
void setup()
{
Serial.begin(9600); //Start the serial connection with the computer
//to view the result open the serial monitor
}
void loop() // run over and over again
{
// getting the voltage reading from the temperature sensor
int reading = analogRead(sensorPin);
// converting that reading to voltage, for 3.3v arduino use 3.3
float voltage = reading * 5.0;
voltage /= 1024.0;
// now print out the temperature
// converting from 10 mv per degree wit 500 mV offset
// to degrees ((voltage - 500mV) times 100)
float temperatureC = (voltage - 0.5) * 100 ;
// print temperature reading
Serial.println(temperatureC);
// wait 100ms
delay(100);
}

Session Info

R version 3.1.2 (2014-10-31)
Platform: x86_64-apple-darwin13.4.0 (64-bit)

locale:
[1] en_GB.UTF-8/en_GB.UTF-8/en_GB.UTF-8/C/en_GB.UTF-8/en_GB.UTF-8

attached base packages:
[1] stats graphics grDevices utils datasets  methods  
[7] base     

loaded via a namespace (and not attached):
[1] tools_3.1.

To leave a comment for the author, please follow the link and comment on their blog: mages' blog.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)