posts tagged with the keyword ‘perl’

2011.07.26

Temperature and Humidity

I’m always annoyed with myself when I don’t publish my code, so this is a follow-up to my Logging the temperature and humidity post.

This whole thing is definitely a work in progress. The hardware has exposed wires, and the software is all just cobbled together pieces. Making something that works is much different than making something that will continue to work, and work properly, and efficiently. Making something that works is a first step. It’s an important step, but it’s only the first step. So let’s begin!

I started with the example from Adafruit over on GitHub and about the only changes I made was to the format output of the data.

// Example testing sketch for various DHT humidity/temperature sensors
// Written by ladyada, public domain

#include "DHT.h"
#define DHTPIN 2     // what pin we're connected to
#define DHTTYPE DHT22   // DHT 22  (AM2302)

DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(9600);
  dht.begin();
  delay(1000);
}

void loop() {
  int h = dht.readHumidity();
  int t = dht.readTemperature();

  // check if returns are valid, if they are NaN (not a number) then something went wrong!
  if (isnan(t) || isnan(h)) {
    Serial.println("Failed to read from DHT");
  } else {
    Serial.print(h);
    Serial.print("\t");
    int temperatureF = (t * 9 / 5) + 32.5;
    Serial.print(temperatureF);
    Serial.print("\n");
  }
}

So this outputs the value for the humidity, then a tab, then the value for the temperature, and then a line return. Oh, I did change the code to output the temperature in Fahrenheit instead of Celcius. If we get a bad value, it’ll print “Failed to read from DHT” though I’ve yet to see that in the log files, I should probably take it out. Also, the Arduino just streams data at a fast rate, much faster than I need. I typically put the sleep functions (to limit the amount of data logged) in my reading code which runs on the computer. I think this is the right way to go, but if you have other ideas, please let me know.

Here’s a fairly simple Processing sketch that will read the data coming in from the Arduino. (Obviously you need the Arduino connected to the computer via USB.)

import processing.serial.*;

PrintWriter output;

Serial myPort;    // The serial port:
PFont myFont;     // The display font:
String inString;  // Input string from serial port:
int lf = 10;      // ASCII linefeed 

void setup () {
  // set the window size:
  size(500,200);
  println(Serial.list());
  myPort = new Serial(this, Serial.list()[0], 9600);
  // don't generate a serialEvent() unless you get a newline character:
  myPort.bufferUntil('\n');
  background(50);
  output = createWriter("output.txt");
}

void draw () {
  // everything happens in the serialEvent()
}

void serialEvent (Serial myPort) {
  // get the ASCII string:
  String inString = myPort.readStringUntil('\n');

    String[] words = split(inString, '\t');
    String humid = words[0];
    String tempe = words[1];

    background(50);
    textSize(40);
    text("   Humidity: " + humid, 40,90);
    text("Temperature: " + tempe, 40,160);

   output.printf("%d-%02d-%02d %02d:%02d:%02d\t%s", year(), month(), day(), hour(), minute(), second(), inString); // Write to the file
   output.flush(); // flush output
}

Besides displaying a small window with the humidity and temperature (seen at the top of this post) it will also log the data to a file named output.txt

Processing Output

2011-07-25 19:09:14     44      91
2011-07-25 19:09:14     44      91
2011-07-25 19:09:15     44      91
2011-07-25 19:09:15     44      91
2011-07-25 19:09:16     44      91
2011-07-25 19:09:17     44      91
2011-07-25 19:09:17     44      91
2011-07-25 19:09:18     44      91
2011-07-25 19:09:18     44      91

This is pretty terrible, as we’re getting way too much data. I should probably add some delay into the Processing sketch, as it’s creating a log file line much faster than the sensor can even output data! This will result in large log files and is just wasteful. If all I wanted was the window showing the current temperature and humidity, I’d probably just delete the logging part of the sketch. Add that to the TODO list. Anyway, it works, and as a proof of concept, it’s a start.

Here’s the Perl code I was using:

#!/usr/bin/perl

use Device::SerialPort;
use IO::Handle; FILE->autoflush(1);
my $port = Device::SerialPort->new("/dev/tty.usbmodemfd411");

$port->baudrate(9600);
$port->databits(8);
$port->parity("none");
$port->stopbits(1);

my $fileout = './templight.log';
my $filerec = './templight-recent.log';

open (FILE, ">>$fileout") or die ("Ooops! Could not open $fileout: $!");

while () {
    # Poll to see if any data is coming in
    my $char = $port->lookfor();

    # If we get data, then print it
    if ($char) {
	$time = localtime(time);
	if (length($char) > 1) {

		my $str = ($time . "\t" . $char . "\n");
		print FILE $str;

		open (FREC, ">$filerec") or die ("Ooops! Could not open $filerec: $!");
		print FREC $str;
		close (FREC);
	}
    }
    # Uncomment the following lines, for slower reading,
    # but lower CPU usage, and to avoid
    # buffer overflow due to sleep function. 

    $port->lookclear;
    sleep (10);
}
close (FILE);

The logging here is a little better than the Processing sketch, at least we add some delay with that sleep at the bottom so our log files won’t be quite as large. We’re saving to two files, templight.log and templight-recent.log. The second one just saves the current data, this just enables us to grab the data from that file and do something else with it, like… send it to Twitter or something.

Perl Output

Tue Jul 26 04:30:39 2011        46      89
Tue Jul 26 04:30:49 2011        46      89
Tue Jul 26 04:30:59 2011        46      89
Tue Jul 26 04:31:09 2011        46      89
Tue Jul 26 04:31:19 2011        46      89
Tue Jul 26 04:31:29 2011        46      89
Tue Jul 26 04:31:39 2011        46      89
Tue Jul 26 04:31:49 2011        46      89
Tue Jul 26 04:31:59 2011        46      89

So our output from Perl looks similar, though we have much less data (but still plenty of data) and the date format is a little different. (Chalk that up to laziness.) Oh, the Perl code also has the serial port hardcoded to /dev/tty.usbmodemfd411, which is lame, and I do have code somewhere to grab the serial port dynamically, but I didn’t implement it yet.

Whew! It feels so liberating to publish all that terrible code… (I mean my own code, not Adafruit’s!) Now I feel the need to start re-writing it and making it less terrible.

2011.01.26

Perl

I needed this script last week… See, our ISP had a bit of downtime, roughly 7 hours of downtime actually, but throughout the day there were some periods where our connection would be up for a few minutes before it went down again.

#!/usr/bin/perl

use Net::Ping;

$p = Net::Ping->new("tcp", 2);
$p->{port_num} = getservbyname("http", "tcp");
$host = 'www.google.com';

while (1) {
if ($p->ping($host)) {
print "Internet is up!\n";
# the next two lines will only be useful on osx
$cmd = 'say -v Victoria "Internet is up"';
system ($cmd);
}
else {
print "...\n";
}
sleep(5);
}

To alert me to these few golden minutes of Internet connectivity I whipped up this script. It keeps trying to reach some server (in this example I’m using the highly-available www.google.com) waiting just 5 seconds between each check, and if it reaches the server (meaning our Internet connection is up) it prints “Internet is up!” and on Mac OS X it also says “Internet is up.” I made it say that so I could keep staring at what I was working on and be alerted audibly when the connection returned.

I was tempted to run this on our Mac jukebox so it would announce to the entire office when the connection was up, but by that time things seemed back to normal.

Obviously you could reverse this code to check if a server is up instead of down, and in fact one of my monitoring systems does just that. If you’re ever at the 2XL Networks office and hear “Attention! The server is not responding!” being yelled from one of the Macs… you know there’s a problem.

2011.01.17

ShiftBrite

Back when I revealed the Twitter Monkey I had a dark secret… I got the Perl script to work, but just barely, and I really didn’t grok exactly how the code worked. I was just thankful MCQN Ltd. published the Alertuino code for me to get started.

I’m happy to say that I’ve made some good progress in getting Perl and the Arduino to talk to each other, and if you keep reading, you’ll see what I’ve got so far.

I’ll be using a ShiftBrite from macetech for this example. You can buy direct for $4.99, get them from Adafruit for $5.00 or use your #freeday money to get one from Sparkfun.

ShiftBrite

To connect the ShiftBrite, you just run it’s GND to the GND on the Arduino, the V+ to the 5V on the Arduino, and the run DI, LI, CI, EI to digital pins 10, 11, 12, 13 respectively, on the Arduino. Just 6 wires… pretty simple.

Once again, I stand on the shoulders of others… a hacker named Ashley Hughes wrote a post titled ShiftBrites and the Arduino and provided a library named shiftbritehughesyarduino. Grab it and drop it in your Arduino/libraries folder before we get started.

The library makes it pretty easy to send a color to the ShiftBrite using a command like this:

sb.sendColour(200,400,600);

Where the colors are in R,G,B value. Though the scale is not 0-255, or 0-100, but 0-1023. I’m not great at math, so I’m going to use the 0-100 scale and just multiply by 10. So for the line above we’d be sending a RED value of 200, a GREEN value of 400, and a BLUE value of 600.

Here’s the code for the Arduino:

/*
 * ShiftBrite.pde
 */

#include "HughesyShiftBrite.h";

HughesyShiftBrite sb;

void setup() {
  sb = HughesyShiftBrite(10,11,12,13);
  sb.sendColour(10,10,10);
  Serial.begin(9600);
}

void loop() {

  int input = Serial.read();

  switch (input) {
  case 48:
    sb.sendColour(0,0,100);
    break;
  case 49:
    sb.sendColour(0,0,200);
    break;
  case 50:
    sb.sendColour(0,0,400);
    break;
  case 51:
    sb.sendColour(0,0,600);
    break;
  case 52:
    sb.sendColour(0,400,0);
    break;
  case 53:
    sb.sendColour(0,600,0);
    break;
  case 54:
    sb.sendColour(0,800,0);
    break;
  case 55:
    sb.sendColour(600,0,0);
    break;
  case 56:
    sb.sendColour(800,0,0);
    break;
  case 57:
    sb.sendColour(1000,0,0);
    break;
  }
  delay(5);
}

See all those “case” commands followed by numbers? They are looking for the ASCII code being sent from the serial port. Don’t have an ASCII chart handy? Look at this simple one and you’ll see that the decimal value for 0 is 48, for 1 is 49, etc. So our case statements are looking for anything between 0 and 9, which is a nice scale to use.

OK, if you’ve uploaded the code, you should see the ShiftBrite lit up, since the initialization sent this:

  sb.sendColour(10,10,10);

The code on the Arduino is now listening to the serial port waiting for some input. The input should be a number between 0 and 9. We should probably send it some numbers… that’s where Perl comes in:

#!/usr/bin/perl
#
# sendserial.pl
#

use Device::SerialPort;

my $port = Device::SerialPort->new("/dev/tty.usbmodem1d21");
$port->databits(8);
$port->baudrate(9600);
$port->parity("none");
$port->stopbits(1);

sleep(3);

for ($i = 0; $i <= 9; $i++) {
	print $i . "\n";
	$port->write("$i");
	sleep(1);
}

exit;

This is the shortest, simplest example I’ve got. You’ll obviously need the Device::SerialPort module installed. If you’ve written anything in Perl (or other languages) this should make some sense. We’re connecting to the serial port (/dev/tty.usbmodem1d21) and sending characters (0 through 9) to it, as well as printing them to the console so you can see them.

When you run the Perl script you should see the ShiftBrite light up and change about once per second, cycling through various levels of blue, green, and red.

Note: We got the port /dev/tty.usbmodem1d21 from the Arduino IDE (though I’ll show you another way to get it) and the sleep command is in there to give things time to initialize. I’ve found that without it, the serial port communication may miss the first commands.

ShiftBrite: Red, Green, Blue

Gotchas: The serial port may change. Mine is ‘/dev/tty.usbmodem1d21′ but it will be different on different machines, and may even change after a reboot. We’ll have a fix for that next time. The other gotcha is that when the Perl script is running, it’s using the serial port, so if you try to upload a new sketch to the Arduino, you will get an error. Since this script only runs for about 13 seconds, you probably won’t hit that problem here… for scripts that loop, you probably will.

I hope that wasn’t too complex. In theory, you could write the Perl part using Ruby, Python, or any scripting language that can do serial communications. In the future I’d like to try to use seriality to see if I can do it via HTML/JavaScript.

In a future installment I’ll have a complete project using all the bits we just covered…. stay tuned!

See Also: Arduino + ShiftBrite Light Organ

2010.12.01

I’m in need of graphing some data, and since I looked at the Google Chart Tools long ago but never did anything interesting with it, I figured I’d give it a spin.

Google’s API is pretty simple to use, you feed it a URL, and you get an image in return. Here’s an example expanded out a bit:


http://chart.apis.google.com/chart?

  cht=lc&
  chs=600x400&
  chg=10,5,5,5&
  chco=ff0000&
  chxt=x,y&
  chxr=1,0,100,5|0,0,24,1&
  chd=t:3,3,3,3,3,3,3,65,38,46,60,59,56,58,36,21,13,62,2,3,3,3,3,2

Each parameter controls some part of the image you get returned. (Want to see it? View the URL.)

You should get something that looks like this:

Chart

Wow… but not really. This is probably one of the simplest examples of a chart, but it serves my purpose.

Of course, since I’m not always content relying on others to host my data, I wanted a way to generate and store the image. You can do that too…

curl -o 20101130.png 'http://chart.apis.google.com/chart?cht=lc&chs=600x400&chg=10,5,5,5&chco=ff0000&chxt=x,y&chxr=1,0,100,5|0,0,24,1&chd=t:3,3,3,3,3,3,3,65,38,46,60,59,56,58,36,21,13,62,2,3,3,3,3,2'

Just use curl to make the request and store the image in a file named 20101130.png (or whatever the date is, or file name you’d prefer.) Obviously you’ll need curl installed. If you need to generate a new chart everyday this is ripe for automating.

I also looked at jQuery Visualize as an option. It’s quite different than the Google Chart API as to how it functions.

Chart

With jQuery Visualize you don’t actually create a chart. Well, you do create a table of data, and jQuery Visualize does all the heavy lifting and creates the chart based entirely on your well-formed tabular data.

I sort of like this approach because there’s no external image files to generate, host, or worry about. You just make a table, and include a bit of Javascript. (Of course there are other concerns/issues, but simplicity is pretty high.)

I’m still evaluating what my final choice will be for my current project. If this were 10 years ago, I probably would have used Perl to generate the image files. If it were 5 years ago, I probably would have used Perl to generate some SVG files…

jQuery Visualize uses the HTML 5 Canvas element, so they get some points in the “innovation” column I guess… Also, jQuery Visualize requires less math, and in my world, the less math I have to do, the better!

2010.11.29

Arduino: The Novel Last year I published a novel for National Novel Writing Month but because I am lazy and a terrible writer, I just wrote a script to write the novel for me. (The results were posted here: National Novel Writing Month.pl)

This year I did it again, and I’ve also published the code I used to write the novel. (See nanowrirobot on GitHub.)

The script needs a source to do it’s work. I did my original development by just pointing it at /usr/share/dict/words which creates some of the most beautiful gibberish you’ve ever seen. You can also just point it at a text file, and it’ll use the words in that. That’s what I did last time, and this time as well. Since this one is titled “Arduino: The Novel” it had better be about the Arduino, right? I ended up creating a word lists from the HomePage, Introduction, FAQ, and ArduinoBoardUno pages of the Arduino web site, and built a list of just under 1,000 words. The results were astounding…

    Written determined appropriate users Flash read SRAM. Protection a board also conditions or By. Lines making process short features draw preceding. Changes functionality please When power edge Not. What For bootloading we’d Windows inputs provides. Try manufacturers screw tutorials dimension teachers avrdude. Without want Single-Sided By leap released diagram. Which Cross-platform their directly pre-assembled bus 3V3. They inexpensive our Google downloaded by Debian. NG module off This standard Ground former. Additional short suggest do based tool Java. Upper commercial length ie up unofficial off. Current cool locally falling Mega Can supported. Board platforms Frequently conveniently map series Circuit. You’re compiles Auto You’ll general OSX compiler. On-board derivative troubleshooting documentation More Stamp Using.

And that’s not all!

    Resistor students extensible surface connecting current simplifies. Possible until Physically name pin number first. In each RESET-EN having inclusion be permission. Outputs explain taken try language help uploading. Discuss protection Mini have Linux to press. Some Be moved along are press process. AnalogReference start step-by-step USB-to-serial protection CAD code. People chip STK500 emphasize might lights OS. Regulator at overwriting works extending pull-up ideas. Comes supply Each requires chip Open-source flash. Sounds limited call timeout AC-to-DC switches mark. Enhancements step-by-step their off name! Hungarian facilitate. Wall-wart we’d permission Reference tool Additionally passed. Back Eagle preassembled support describe COM distributors. Principles Forum via powered boards page multimedia. Corresponding particular Vin conveniently layer addition overheat.

Wow! Have you ever read a computer generated novel about a microcontroller with such suspense, drama, and intrigue!?

And look! You can download it in a variety of formats:

Actually, it’s pretty terrible, unless you are a fan of random acts of writing. If you want some writing that makes sense, take a look at nanowrimo.org, where you can find information about novels written by real people.

If you’re more interested in microcontrollers (specifically the Arduino) maybe you want to read about a Trashcan Accelerometer, or Baker Tweet, or a steampunk bandwidth meter

« Older Entries |

buy the button:

But The Button

recently at:


top recent artists: