logging data with adafruit io using raspberry pi and cURL

adafruit io data logging
adafruit io data logging

adafruit.com is my preferred provider for prototyping supplies, raspberry pi devices, and most of all  breakout boards.  I just recently starting using the free version of their data logging service and I am very impressed.

I have an MCP9808 i2c temperature sensor connected to a pi3 set up in my garage.  I wrote a perl module to get the temperature from the MCP9808:

package MCP9808;
use strict;
use RPi::I2C;

experimenting with MCP9808 temperature sensor
ambient temp register returns 2's complement

ambient temp register is 0x05, returns 16-bit result;
bits 15-13 must be masked out, bit 12 is sign bit, 
12-bit result is 11-0b.  Lower byte 0-7b, upper byte
8-15b.  Conversion to decimal:
Temp = (upperbyte * 2^4) + (lowerbyte * 2-4)

sub new {
	#constructor, taked I2C addr as arg
	my $self = { addr => $_[1]  };
	bless ($self, "MCP9808");
	#print "addr:\t", $self->{addr}, "\n";
	return $self;
}#end new

sub read_temp{
	my $self = shift;

	my @result = ();
	my $tempdev = RPi::I2C->new($self->{addr});

	#read 2 bytes from temp register 0x05
	#returns array, upper byte, lower byte
	my @reading = $tempdev->read_block(2, 0x05);

	#convert reading to decimal temp
	my $ubyte = $reading[0];
	#strip 15-13b
	if($ubyte > 127){$ubyte-=128;}
	if($ubyte > 63){$ubyte-=64;}
	if($ubyte > 31){$ubyte-=32;}
	my $celsius = ($ubyte * 16) + ($reading[1] * 0.0625);
	my $farenheit = ($celsius * 1.8) + 32;
	push @result, $celsius;
	push @result, $farenheit;

	return @result;
}#end read_temp


I had an existing script to get the current temperature from the mcp9808 and display the time and temperature on a 4×20 LCD display.    I only had to change one line of code to get it to post my readings to adafruit io

use strict;
use Time::HiRes qw(usleep);
use MCP9808;
#require "/home/pi/gpio/MAX7219.pl";

my $t1 = MCP9808->new(0x18);

#init timer
my $begin = time();
my $hr = 0;
my $min = 0;
my $sec = 0;
my $time_val = $hr."-".$min."-".$sec;

	my $now = time();
	my $tsec = $now - $begin;

	my @res = $t1->read_temp();
	my $deg_f = sprintf("%2.1f", $res[1]);

	#calc min / sec
	$hr  = ($tsec / 60) / 60 ;
	$hr = int($hr);
	$min = $tsec / 60;
	$min = int($min);
	$sec = $tsec%60;
	$sec = int($sec);
	#print length($sec)."\n";
	if($sec == 60){
		$sec = 0;
	}#end if
	if($min >= 60){
		$min = $min - ($hr * 60);
	}#end if

	if(length($min) eq 1){ $min = "0".$min; }
	if(length($sec) eq 1){ $sec = "0".$sec; }
	if(length($hr) eq 1){ $hr = "0".$hr; }

	#linux date command output
	my $time_val1 = `date`; 
	print $time_val1;

	if($tsec > 0){
		$time_val = $hr.":".$min.":".$sec;
		#print_sentence($time_val, 500, 1);
		#`./lcd "Temp: $deg_f F        Time: $time_val"`;
		`./lcd "Temp: $deg_f F        $time_val1"`;
		#send data to adafruit.io
		curl -H 'X-AIO-Key: 2347yfudnvuefh378myaiokeygoeshere2h8f' -H 'Content-Type: application/json' -X POST -d '{"datum":{"value": "$deg_f"}}' https://io.adafruit.com/api/v2/icom032/feeds/garage-temperature/data
	}#end if

}#end for

this is the line of code that posts my temperature measurements to adafruit io:

curl -H 'X-AIO-Key: fudnvuefh378myaiokeygoeshere2h8f' -H 'Content-Type: application/json' -X POST -d '{"datum":{"value": "$deg_f"}}' https://io.adafruit.com/api/v2/icom032/feeds/garage-temperature/data

I changed my key, of course.  curl can be used for development boards that run a full linux distribution.  There are other libraries for devices like arduino.  I am amazed at how simple they made it.

The charts look cool, scales automatically, updates in near real time, and has cool mouse-over effects.

adafruit.io graph of MCP9808 temperature sensor in my garage connected to raspberry pi 3
adafruit.io graph of MCP9808 temperature sensor in my garage connected to raspberry pi 3

I downloaded my data in csv format and graphed it using my own perl tk csv database analysis tool.  It matches up pretty well, but the adafruit graphs are way cooler!

perl Tk csv database analysis tool
my own perl Tk csv database analysis tool graphing the same data I downloaded

I have a lot of ideas I want to try and integrate into adafruit IO.  Here is three days worth of readings from my temperature sensor in the garage->

adafruit IO interactive real-time graph
adafruit IO interactive real-time graph

oui mac address identifier utility with perl

wireshark has a good online oui lookup utility that will tell you the manufacturer of a particular network interface card based on the first six bytes of the mac address referred to as the oui (organizationally unique identifier).  nmap, at least the version on my ubuntu machine, has this feature but I am dissatisfied with it’s accuracy or lack thereof.  Being fond of perl,  I searched cpan.org before I attempted to reinvent the wheel.  I found the Net::MAC::Vendor module.  I found it to be slow, and relied on querying an online database (which didn’t work well).

I decided to write my own to augment the functionality of my own network scanner.  I downloaded a local copy of the text file provided by wireshark and wrote the following script to scan my local arp cache and tell me the manufacturer of  each device on the network.

#!/usr/bin/perl -w
use strict;

#update arp table
`arp > arp.txt`;

open(AF, '<', 'arp.txt') or die $!;

	if($_ =~ /(\d+\.\d+\.\d+\.\d+).+(..:..:..)(:..:..:..)/){
		my $match_flag = 0; 
		my $ip = $1;
		my $oui = $2;
		print "$ip\t$oui$3\t";
		open(OU, '<', 'oui_mac.txt') or die $!; 
			#open oui file and search
			my $i=0;
				#print "$oui \n";
				if($_  =~ /$oui/i){
					print "$_";
					$match_flag = 1;
				}#end if
			}#end while
		close OU;
		if($match_flag == 0){
			print "NO OUI MATCH!\n";
		}#end if
	}#end if
}#end while

close AF;

Simple and effective.

mac oui lookup tool written in perl
mac oui lookup tool written in perl

family alarm clock project III

trinket Pro 5V 16MHz based alarm clock / stereo project using a PCF8523 real time clock breakout from adafruit
trinket Pro 5V 16MHz based alarm clock / stereo project using a PCF8523 real time clock breakout from adafruit

Nearly done with our family project.  It has been so much fun, and I hate that it’s nearly over, but Eli and Addy are pumped for another project.  The maker space  has been the new cool hangout:  loud music, chips + cheese dip, Teen titans Go, roller skating, and making a killer boom box that everybody loves.

trinket Pro 5V 16MHz based alarm clock / stereo project using a PCF8523 real time clock breakout from adafruit
the brains is a trinket Pro 5V 16MHz

This is my first project with a trinket Pro.  I love this platform.  Tiny, cheap, powerful,  easy to use; comparable to an arduino nano.  I did run out of GPIO pins (mostly due the the 16×2 LCD display), but got around it adding an MCP23008 for the alarm control buttons (also using libraries from adafruit) .

PCF8523 adafruit trinktet project
It’s adisaster on the inside, but pretty cool on the outside.