Mar
1
Gratifying Graphic Gizmos
15 years ago, at the start of March | 2 Comments
Yesterday the Current Cost unit actually got installed for real, something I was dreading. Dreading not because it was a difficult thing to do but simply because I expected the figure it would show would be terrible. Guess what, it wasn’t. In fact it seemed to be fairly close to that of other people who are monitoring theirs. The initial figure of 371 Watts didn’t last too long once the dishwasher and oven came on and an interesting spike appeared when the hob went on for the kettle.
Continuing with my sudden graphing fetish, as well as using a Current Cost unit I have dotted a number of little devices I’ve built with Xbee and Arduinos to measure temperatures (and other things) around the house. More information on those will come out later, but it’s an interesting project too.
Since I have the data for those it’d be rude not to graph them too, there’s a sample in the thumbnails below.
Not content with graphing them locally I picked up a Pachube invite and started graphing data there too. The process is simple really and as you can see on the right hand side of this page under ‘Graphy Stuff’, graph images can be embedded in your own or other sites. The really interesting thing about Pachube is that you can share your data with people who may be interested. The data they get to see is delayed by approximately 15 minutes. If you output your data in the eeml format then you can specify your own tags too.
Tagged with: 1-Wire • arduino • development • environment • hardware • monitoring • Pachube • software
March 1, 2009 8:47
Feb
4
One Wireduino made easy
15 years ago, at the start of February | 12 Comments
For a very long time now I’ve been playing with the Arduino boards but it wasn’t until I recently discovered some DS1820 1-wire chips in my parts box that I started even thinking about 1-wire stuff. Connecting 1-wire devices to the Arduino is, well, amazingly simple. Using the sample circuit from the datasheet we can see the connections are few and far between.
Please note that this is the corrected circuit, previously the VDD was not tied to ground. While the circuit would work it would only give reliable results on very short runs. This circuit allows longer runs to the sensor.
Coding this up is also made extremely easy with the OneWire library. I’ve put together a little application below that will read all of the 1-wire devices on a bus. If you press L in the Arduino IDE serial monitor it will list all the 1-Wire device id’s and if you press T you’ll get the id and temperature reading.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | /* Simple 1-wire device reading Pass T over serial to get temperatures Pass L to list 1-wire devices */ #include <OneWire.h> #include <stdio.h> #define CONVERT 0x44 #define READSCRATCH 0xBE #define SKIP_ROM 0xCC #define MATCH_ROM 0x55 OneWire ds(10); // The DS18S20 is connected on pin 10 int ledPin = 13; // flash an led on 13 - we all like flashing lights void setup(void) { // initialize inputs/outputs // start serial port Serial.begin(9600); pinMode(ledPin, OUTPUT); //we'll use the led to output a heartbeat } void loop(void) { int incomingByte = 0; if (Serial.available() > 0) { // read the incoming byte: incomingByte = Serial.read(); // say what you got: //Serial.print("I received: "); //Serial.println(incomingByte, DEC); if (incomingByte == 84) { getStuff(); Serial.print("\r\n^"); } else if (incomingByte == 76) { listDevices(); } } } void listDevices(void) { byte addr[8]; ds.reset_search(); while(ds.search(addr)) { digitalWrite(ledPin, HIGH); // sets the LED on if ( OneWire::crc8( addr, 7) == addr[7]) { if ( addr[0] == 0x10) { // Make sure it is a DS18S20 device char buffer[512]; sprintf(buffer,"Id:%02x%02x%02x%02x%02x%02x%02x%02x\r\n", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7]); Serial.print(buffer); } } } Serial.print('^'); } void getStuff(void) { byte i; byte present = 0; byte data[12]; byte addr[8]; char buff[15]; float real_temp; float temp_count; float read_temp; ds.reset_search(); while(ds.search(addr)) { digitalWrite(ledPin, HIGH); // sets the LED on if ( OneWire::crc8( addr, 7) != addr[7]) { // Check CRC is valid Serial.print("CRC is not valid"); } if ( addr[0] != 0x10) { // Make sure it is a DS18x20 device Serial.print("Device is not a DS18x20 family device."); } ds.reset(); // Reset device ds.select(addr); // Select device ds.write(CONVERT,1); // Issue Convert command delay(1000); // maybe 750ms is enough, maybe not digitalWrite(ledPin, LOW); // sets the LED off present = ds.reset(); // Reset device ds.select(addr); // Select device ds.write(READSCRATCH); // Read Scratchpad for ( i = 0; i < 9; i++) { // we need 9 bytes data[i] = ds.read(); } if(OneWire::crc8( data, 8) == data[8]) { // Check CRC is valid // CRC is ok // Divide the temperature by 2 - note the » and // « need to be replaced with double < and > // wordpress kills the server when you try to // save otherwise. read_temp=((data[1]«8) | data[0]) » 1 ; // Convert to real temperature temp_count=float(data[7] - data[6])/(float)data[7]; real_temp = ((float)read_temp-0.25)+temp_count; // Convert float to ascii tempToAscii(real_temp,buff); char buffer[512]; sprintf(buffer,"%02x%02x%02x%02x%02x%02x%02x%02x %s\r\n", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7], buff); Serial.print(buffer); } else { Serial.println("CRC Failed"); } } void tempToAscii(double temp, char *buff) { int frac; //get three numbers to the right of the decimal point frac=(unsigned int)(temp*1000)%1000; itoa((int)temp,buff,10); strcat(buff,"."); //put the frac after the decimal itoa(frac,&buff[strlen(buff)],10); } |
There’s also a copy of the .pde file that you can download if you feel more inclined. It’s not an exact copy, I removed the commented out xml for the above version. It’s worth pointing out that this circuit is using what is called parasitic power, which means your cable run should be shortish. If you want to use an external power supply then pin 3 (VDD) on the DS18S20 should go to your external supply. This would allow for much longer runs of cable. Below is an example graph generated by cacti with 2 DS1820’s connected the the arduino. As you can see the temperatures aren’t exactly the same but this is to be expected since the accuracy of the DS1820 is +/- 0.5 ° C
The breaks in the graph were caused my me removing the USB plug from the PC it was connected to so that I could make some minor alterations to the circuit.
Josh asked how I was getting the input for Cacti, here’s the perl script I use
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #!/usr/bin/perl $output = `echo -en "T" >>/dev/ttyUSB0 && cat /dev/ttyUSB0`; @lines = split(/\r\n/,$output); $t=1; foreach $line (@lines) { @spl = split(/\s+/,$line); $lc = @spl; if ($lc gt 1) { $node=$spl[0]; $val=$spl[1]; print "Temperature_$node:$val "; } $t++; } |
This outputs Temperature_x:n where x is the 1-Wire id and n is the temperature. It could probably do with tidying up and if you wanted to you could pass the 1-Wire id to the script to and only output the temperature for that particular 1-Wire device. A copy of the exported Cacti template can be downloaded, I’m hoping that you just need to import that into your Cacti after placing the script in the scripts directory. Just remember, under linux, if you unplug and replug in your Arduino you may need to set the tty port speed to 9600 (or whatever you put in your Serial.begin(); ). You can use the following command for that;
1 2 3 | stty -F /dev/ttyUSB0 cs8 9600 ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke noflsh -ixon -crtscts |
Make sure that ttyUSB0 is what your Arduino is connected to first. If not you will need to change it in the perl script and on the line above.
Tagged with: 1-Wire • arduino • hardware • opensource • software
February 4, 2009 21:46
Feb
18
USB Controlled RGB Blob
16 years ago, mid-February | 6 Comments
I recently came across a little project which would turn on an LED box when there was mail your gmail account. I thought it was quite interesting and, since I’d had an Arduino Diecimila in my laptop bag for about 6 months and not touched it, I decided to replicate it. The idea was simply to get used to how the Arduino board worked, the project in itself isn’t exactly going to push anyone to their limit. I was right, the code was basically in the examples there was nothing to do. Since we’re selling our house lots of my electronics development stuff has ended up in the loft. I went for a rummage and found some little RGB light globes that a local garden centre had been trying to sell off cheaply at a couple of Euros each. Undoing the screws on the base of the globe revealed a very simple
design, I’d just need to tap into the LEDs and disconnect the chip they used. Before any of this was going to happen I needed to build some sort of prototype to at least be sure that the concept was going to work. Since I didn’t have any RGB LEDs or even one of each red, green and blue I had to settle for a small LED board that had come from an old piece of equipment that I’d bought, literally, just for the parts. There was a slight problem. The led board was red, green and errm… orange. It didn’t really matter at this stage, I was only proving the code and making sure that I could get the whole idea to work before destroying the perfectly useless light globes.
The software side was also fairly straight forward too. In the end I used the SimpleMessageSystem library to handle the serial data since I kept running into issues with the standard serial I/O routines. The SimpleMessageSystem routines basically use white space as variable separators and a <CR> to signify the end of input.
Each of the colour channels can have a value between 0 (zero) and 255 which gives a lot of variation. There’s also the option to pulse the mixed colours.
Initially I was just going to have the 3 LEDs change to their relative brightness but then I hit on the idea of having them fade up and down to the correct value. I have to say it looks much better with the gradual change, although I might just add the option of selecting either gradual or instant to the parameter list.
Now, with a simple command, I can set the RGB value of my light globe.
./rgb-globe -l -b 9600 -p/dev/ttyUSB0 -s “1 255 50 0”
The original code for the command line application came from Tod Kurt and was written to be able to send serial data to the Arduino. I did make some modifications, including a couple of virtual slappings of Tod for using strcpy – I still don’t understand why people don’t pretend that function just does not exist.
I’m considering writing a small GTK application that just has a colour picker to select colours, but that would be in addition to the command line application since this is designed to be used from things like scripts or mail and IM notifications or, as I suspect mine will, build status information for my Openmoko buildhost. The only real issue at the moment is that it’s really not bright enough, I think I need to rethink the orb – maybe it’ll be better at night…
Tagged with: arduino • hardware • linux • software
February 18, 2008 16:46
Current Electricity Use (15min)
iPhone/Webkit RSS Reader
Links
- automated home
- Automated It Technology News
- awooga!!!
- LinITX
- My Acer page
- My Asterisk pages
- My Work in progress (old)
- Noble Race Car
- openmoko / neo 1973 wiki
- planet openmoko
- Spadgecock Cumpants