Arduino to Pachube Interfacing

I've just started checking out Pachube I am trying to graph temperature with a basic arduino temperature sensing circuit: (LM335A Temperature Sensor)

This website (http://dailyduino.com/archives/616) is where I got the processing code from, and it says to upload Standard Firmata to the arduino. I do have the EEML and Pachuino libraries installed. I copied the processing code, and changed it a little bit to work properly with my arduino.

import processing.serial.*;
import cc.arduino.*;
import eeml.*;
import pachuino.*;

Pachuino p;
Arduino arduino;
int ledPin = 13;

void setup(){
p = new Pachuino(this, Arduino.list()[1], 9600);
p.manualUpdate("http://www.pachube.com/api/feeds/8728.xml"); 
p.setKey("My API code goes here");

// local sensors
p.addLocalSensor("analog", 1,"temperature, indoor");
}

void draw(){
//p.debug();


delay(1000);
}

// you don't need to change any of these

void onReceiveEEML(DataIn d){
p.updateRemoteSensors(d);
}

When I run the processing code, my Pachube feed is updated, but the value is always at 0.0, so somewhere along the lines, the temperature sensor value is not read. Do I need to change something in the Arduino code, or the Processing code? I've been working with this for about 2 hours, and I just can't find the solution. :-/

Thanks a ton! :wink:
-duemilanove

I don’t think you have the sensor wired correctly. I haven’t used that chip but it’s datasheet application section clearly shows a load resistor required. In fact without such a resistor you may have damaged the sensor, but I can’t state that for sure.

http://www.national.com/ds/LM/LM135.pdf

Lefty

I don't think you have the sensor wired correctly. I haven't used that chip but it's datasheet application section clearly shows a load resistor required. In fact without such a resistor you may have damaged the sensor, but I can't state that for sure.

Thanks for the reply, Lefty. I received this item in a kit, and there was no specification that it needed a resistor, and it worked perfectly fine the last time I used it without a resistor. The documentation that came with the kit is here: http://www.sparkfun.com/tutorial/AIK/ARDX-EG-SPAR-WEB.pdf (pg. 28 is the temperature sensor documentation)

-duemilanove

LM335A Temperature Sensor

I hate to break it to you, but the connection on the Sparkfun sheet is for an Analog Devices TMP35/TMP36/TMP37 device, not a National Semiconductor LM335. (Follow the sparkfun link to Ardx.org and it shows, in large bold print, that it's a TMP36.)

[edit]I should have noted that the Analog Devices TMP35/TMP36/TMP37/TMP37 referred to on the ardx page corresponds to the National Semiconductor LM35. The important point is that the Sparkfun document says that it is an LM335 which is NOT the same as an LM35 or a TMP35/TMP36/TMP37. The Sparkfun picture shows connections that are OK for an LM35, not an LM335. Sloppy, incorrect, and downright frustrating.[/edit]

Here's the data sheet for the TMP36: TMP35 Datasheet and Product Info | Analog Devices

Compare with the LM335 on the link that Lefty gave. Not only is there a resistor (required) for the LM335 in every example, the pinouts are different! The center pin on the LM335 goes (through a resistor) to +5V. The center pin on the TMP36 goes to the Arduino analog input pin. Hmm...

So: Do you really have an LM335? Or is it a TMP36? Or what?

If Sparkfun sent an LM335 and showed connections for a TMP36, then I think they owe you an explanation (and, probably, a new chip).

I have used the LM335, and, as far as I can tell, it works as advertised when connected as shown in the manufacturer's data sheet. Using it uncalibrated gave results consistent with the error specification (a couple of degrees K).

If it's an LM335, you can test it as follows:

Hook up the LM335 as shown on the National Semiconductor data sheet. I used a 2.2K Ohm resistor between the LM335 center pin and +5V, but you can use just about anything from 1K to 10K. Note particularly that the pin diagram shown in the data sheet is the bottom view, so make sure you get the left and right pins right.

Write a simple Arduino sketch that reads analog pin 0 and uses Serial.print() to display the result. At "room temperature" (24 C), the reading should be somewhere around 598 (plus or minus a few counts, depending on the exact value of the +5V supply on your board).

Regards,

Dave

hi!
i am using similar temperature sensor LM35CZ. I use it without resistor and i have connected it the way you showed on the first post.

You can try if this code works (prints temp to serial monitor)

//declare variables
float tempC;
int tempPin = 0;

void setup()
{
Serial.begin(9600); //opens serial port, sets data rate to 9600 bps
}

void loop()
{
tempC = analogRead(tempPin);           //read the value from the sensor
tempC = (5.0 * tempC * 100.0)/1024.0;  //convert the analog data to temperature
Serial.print((byte)tempC);             //send the data to the computer
delay(1000);                           //wait one second before sending new data
}

i got this code from: My Projects: Arduino LM35 Sensor

So:  Do you really have an LM335? Or is it a TMP36?  Or what?

The name is written on the sensor

AND .. i found Pachube really interesting... it is more simple that doing own server with temp script.. definitely gonna try it out!

LM35CZ...The name is written on the sensor

Yes! The LM35 is approximately equivalent to the TMP36 that the ardx.org link from the Sparkfun sheet shows. I edited my previous post to add this information.

Summary:
The LM35 is not (that's not) the same as an LM335 that the Original Poster says is being used. Software is different (LM335 gives temp in hundredths of a degree K, not C). Hardware is different (different pinouts, LM335 requires a resistor).

Regards,

Dave

Thanks for all your useful replies! :slight_smile: I'll answer some of your questions now.


I hate to break it to you, but the connection on the Sparkfun sheet is for an Analog Devices TMP35/TMP36/TMP37 device, not a National Semiconductor LM335. (Follow the sparkfun link to http://ardx.org/BBLS10S/ and it shows, in large bold print, that it's a TMP36.)

Oomlout and Sparkfun both offer this kit. Sparkfun put LM335 temperature sensors in their kit, and Oomlout threw in a TMP36. The weird part is, is that Sparkfun led me to all of Oomlout's code samples (which stated a TMP36 sensor), and online documentation. In the Sparkfun instruction manual (I posted the pdf above), it says that it was a LM335 temperature sensor, and in a circuit overlay that came with my kit from Sparkfun. http://www.sparkfun.com/tutorial/AIK/CIRC00-sheet-SPAR.pdf Page 10 shows in large bold print that it *is a LM335 temperature sensor*.[/u]
---
> Do you really have an LM335? Or is it a TMP36? Or what?
On the sensor, it says LM335.
---
> If it's an LM335, you can test it as follows:
>
> Hook up the LM335 as shown on the National Semiconductor data sheet. I used a 2.2K Ohm resistor between the LM335 center pin and +5V, but you can use just about anything from 1K to 10K. Note particularly that the pin diagram shown in the data sheet is the bottom view, so make sure you get the left and right pins right.
>
> Write a simple Arduino sketch that reads analog pin 0 and uses Serial.print() to display the result. At "room temperature" (24 C), the reading should be somewhere around 598 (plus or minus a few counts, depending on the exact value of the +5V supply on your board).
Okay, I did this experimentation with a 10K resistor, and used this code:
```
[u]//declare variables
float tempC;
int tempPin = 0;

void setup()
{
Serial.begin(9600); //opens serial port, sets data rate to 9600 bps
}

void loop()
{
tempC = analogRead(tempPin);           //read the value from the sensor
tempC = (5.0 * tempC * 10.0)/1024;  //convert the analog data to temperature
Serial.println(tempC);             //send the data to the computer
delay(1000);                           //wait one second before sending new data
}[/u]
```
In the temperature code sample that was in the kit, and the code that was posted by D3C3PT1C0N, it says to multiply by 100, not 10, but I when multiplying by 100 I get a number like: 290, so I multiply by 10 to get a more realistic degree value, which is about 29 degrees Celsius. I guess that is sort of close to room temperature. I took out the resistor, and the numbers between 28 and 29 degrees C were displayed. I put the temp sensor under my propped up laptop where it was at least 5 degrees warmer than room temperature for about a minute, and it displayed some numbers between 28 and 29 degrees C. I don't know if it takes long for the sensor to react to different temperatures though.
---
I hope this clears some things up. I don't want to really make to much of a deal out of it, but it is an issue. :-/
Thanks for all the help!
-duemilanove

it says to multiply by 100, not 10, but I when multiplying by 100 I get a number like: 290, so I multiply by 10 to get a more realistic degree value,

Well, that's just wrong (really, really wrong). I mean, if the formula doesn't agree with your expectations, just change the formula???

Well, let's try to do a little better. Instead of using your reading, I'll use mine. (You didn't tell me your reading, so I couldn't use it even if I wanted to.) Instead of faking the calculations to try to get the "right answer," I'll calculate an "answer" and see if I think it's "right." (See Footnote.)

Here's the drill:

The voltage out of the LM335 is approximately equal to hundredths of a degree K. (That's Kelvin, not Celsius)

Now, if your Arduino +5 Voltage is exactly 5.0, here's the way to convert the 10-bit ADC reading (a long int) to Volts:

float aVcc, adcVolts degreesK, degreesC, degreesF;
aVcc = 5.0; // If you have a voltmeter put the actual value here
adcVolts = adcReading * aVcc / 1024.0
degreesK = 100.0 * adcVolts;
degreesC = degreesK - 273.15;
// I'll let you fill in the Fahrenheit calculation if you are interested.

Feel free to print out all intermediate calculated values.

Then, you can consolidate the code into a single expression if it suits your fancy.

My example, sitting in my comfortable room:

10-bit ADC reading = 598 (decimal)
If I assume aVcc = 5.0 volts, this means that adcVolts is equal to 2.92 volts. This is 292 degrees K, which is 18.84 C (65.9 F). Hmmm...It feels a little warmer than that to me. I mean, the LM335 has an error rating of a couple of degrees, but I think it's even a little warmer than that.

Now, I happen to have a digital voltmeter that I got at a garage sale a few years ago, and when I measure the "+5" volt supply on my Arduino Duemilanove, I get 5.10 Volts (2% higher than nominal, but easily within the allowable tolerance of 5%). Now, 2% doesn't sound too bad, right? After all the LM335 device itself is only specified to be accurate to a couple of degrees.

However...

If I plug this value of aVcc into the formula, I find that the ADC reading of 598 actually represents 2.98 Volts (2% higher than 2.92 so that's consistent). This means that I am measuring 298 degrees K, which is about 24.68 C. (76.4 F) Ahhh. Just right. (Note that I can measure voltage on the analog input pin with my meter, and, in fact, I see 2.98 Volts, so the Arduino is apparently working very well---at least for this reading.)

Note that, since the voltage is proportional to degrees Kelvin, it turns out that a 2% error in the reference voltage makes a difference of something like 10 degrees F in the calculated value at room temperature.

Bottom line: If you don't have a voltmeter, use 5.0 in the formula, but accept the possibility of errors on the order of ten (or maybe more) degrees F.

Regards,

Dave

Footnote: One of the first things we learn in lab,and what our lab instructors try to discourage: "If you know the right answer, you can get the right answer." If you can't fake the data, then fake the calculations. Just turn it in on time and maybe the poor overworked TA won't notice the chicanery. Then, some day you can get a job at an institute that gets lots of grants (big bucks) for tracking data that proves something about global warming and... (Oh, man! Don't get me started!)

Thanks, Dave, for all of your information and thoughts. I do appreciate it, and I learn by a lot of mistakes I make, so thanks for pointing a lot of them out. :slight_smile: I don't know why I had to change the 100 to a 10, because now when I tried the formulas you gave me, they worked out perfectly without changing anything. This is the sample code reading just the the output from the temperature sensor without any formulas attached:

int temperaturePin = 0; 
                        //the resolution is 10 mV / degree centigrade 
                        //(500 mV offset) to make negative temperatures an option

/*
 * setup() - this function runs once when you turn your Arduino on
 * We initialize the serial connection with the computer
 */
void setup()
{
  Serial.begin(9600);  //Start the serial connection with the copmuter
                       //to view the result open the serial monitor 
                       //last button beneath the file bar (looks like a box with an antenae)
}
 
void loop()                     // run over and over again
{
 float temperature = getVoltage(temperaturePin);  //getting the voltage reading from the temperature sensor

                                                  //to degrees ((volatge - 500mV) times 100)
 Serial.println(temperature);                     //printing the result
 delay(1000);                                     //waiting a second
}

/*
 * getVoltage() - returns the voltage on the analog input defined by
 * pin
 */
float getVoltage(int pin){
 return (analogRead(pin) * .004882814); //converting from a 0 to 1024 digital range
                                        // to 0 to 5 volts (each 1 reading equals ~ 5 millivolts
}

With this code, these were some of my results:

3.01
3.02
3.02
3.02
3.02
3.02
3.02
3.02
3.02
3.02
3.02
3.02
3.02
3.02
3.02
3.02

If these results are what you mentioned 'adcVolts', that means that most of the numbers equal 302 Kelvins.

In the code, I added the forumla, giving me degrees in Celsius:

temperature = ((100*temperature)-273.15);

and my results were as follows:

29.10
28.61
28.61
29.10
28.61
28.61
28.61
28.61
28.61
28.61
28.61
29.10

So, it looks like my temperature sensor is sensing around room temperature, and because I don't have a voltmeter to check my arduino's actual voltage, it is a few (about 4) degrees off normal room temp.


So, am I on the right track now? It looks like things are working out now, and just to be on the safe side, I'll use a resistor when working with that temperature sensor.

-duemilanove

So, it looks like my temperature sensor is sensing around room temperature, and because I don't have a voltmeter to check my arduino's actual voltage

But you can calculate the applied voltage indirectly but just taking the 'raw' value from a analogRead() statement which gives you a raw count from 0-1023. Take the raw count and multiply it by .0048 and you will get the 'raw' voltage being applied to the pin, give or take a few counts depending on how close to +5vdc the actual board voltage is.

Lefty

am I on the right track now?

Looks good.

Here are a couple of suggestions.:

Look at the entire program and clean it up so that everything is valid. Even the comments! Delete the comment about 500 mV offset. There is no 500 mV offset in the hardware or software.

That might have been required in hardware if you were using a sensor like the LM35 whose voltage is proportional to degrees C and you wanted to measure temperatures below zero.

Since we are using an LM335, which has an output that is proportional to degrees K, we really (really) don't have to worry about negative temperatures, right?

My point is that a working program and its comments are a valuable resource. If you come back to this later, or if you decide to share it with someone, misleading (incorrect) comments waste everyone's time.

Also, other people might take a look at such things and decide that it's not worth pursuing even though the code itself might actually work.

With that in mind, consider that expressions like [color=#ff0000]analogRead(pin) * .004882814[/color] are abhorrent to programmers who might want to maintain, debug, or enhance the code. They wonder (and go to the data sheet and go to a calculator) before figuring out that the "magic number "[color=#ff0000].0048828141[/color]" comes from 5.0/1024.0 Here's a fact: If you write the expression [color=#ff0000]analogRead(pin) *5.0/1024.0[/color] in your code, any modern compiler (like the one that Arduino uses) calculates the constant at compile time and inserts the correct number into the machine code. It doesn't occupy any more code space and doesn't take any more time to run the instruction, and it's easy to see how to change it if you decide to modify the code (to use a voltage other than 5.0 in the calculations, for example). Just put it in your comment what the formula actually means.

Anyhow: Good job!

Regards,

Dave

Look at the entire program and clean it up so that everything is valid. Even the comments!

Yep, that was my plan after making things work out properly. :wink:
Thanks for the other tips, you have been a great help to me. :slight_smile:


Well, now that the details about the temperature sensor are all sorted out, I'd like to get some input about the original topic about Pachube to Arduino Interfacing. I've come up with some ideas, so I will try them, but if you have any suggestions, please reply.

Thanks a bunch!
-duemilanove

http://fritzing.org/projects/lm335-temperature-sensor/

LM335 Temperature Sensor

Thanks for the reply, D3C3PT1C0N
I haven't tried, but I don't think that will help me out too much because in that project, they used an Ethernet Shield. I'm connecting through the computer's USB port, and processing, which can be done. Currently my arduino is reading its temperature, and writing it to a variable called 'temperature'. Could processing read variable 'temperature' coming from the arduino, and post it on Pachube?