Show Posts
Pages: [1] 2 3
1  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: Please update OneWire page for DS18B20 on: January 29, 2009, 08:44:09 am
You need to download and install the OneWire library - it's not included as part of the Arduino distribution.   You should download the most recent version of the library from
this page

http://homepage.mac.com/wtpollard/Software/FileSharing7.html

unzip it, and copy the OneWire directory into your Arduino hardware/libraries folder.  There's a page on the Arduino playground with some examples of how to use the library.

http://www.arduino.cc/playground/Learning/OneWire
2  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: Please update OneWire page for DS18B20 on: January 09, 2009, 10:55:43 am
Quote
It looks like it can take a while to read the temperature via the library. A second or more and the Arduino can't do anything else during this time. I guess the library calls delay().
The reason it takes so long is that you need to give the DS18B20 750ms to take a temperature reading.  The commands to start that process and to actually read the temperature from the device are fairly quick.  Luckily for you, this delay is executed in user code (not in the OneWire library functions), so it should be easy for you to do other things in that period; just be sure not to try to read the temperature before the chip has been given enough time to record it.

If you have any more detailed questions about how to do this, just post your code here and I'll try to help.
3  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: Please update OneWire page for DS18B20 on: April 21, 2008, 09:37:10 pm
Quote
Okay I think I understand what most of those lines of code do but can you explain what this line is saying?

temp_frac = temp_raw & 0x0F;

This copies the least-significant four bits of temp_raw to temp_frac.   The '&' operator does a bitwise AND between its two arguments, and 0x0F is the hexadecimal for 00001111.

Quote
You also have this line but I don't see an integer called "count".

Serial.print(count);

Does this have something to do with the fact that you are using it as a temperature logger?  As in you have an integer called count somewhere in there that increments +1 every iteration of the program to keep track of the temperatures?

Sorry about that!  I didn't notice I had left that in there.  Yes, this is the count of the number of temperature readings I've taken.

Quote
Sorry for all of the questions.  I am very green when it comes to any kind of programming but I am catching on slowly.
You never need to apologize for asking questions.  The only way to learn is to try stuff out and ask questions when you run into problems.
4  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: Please update OneWire page for DS18B20 on: April 21, 2008, 03:43:49 pm
Quote
Is there a command similar to Serial.print that doesn't truncate the number?

Not that I'm aware of, but I'm not an expert.  What I did when I first wanted to get nicely formatted temperatures output to the console was the following...
Code:
 int temp_raw = (data[1] << 8) + data[0];
  if (temp_raw > 0) {
    temp_int = temp_raw >> 4;
    temp_frac = temp_raw & 0x0F;
  }
  else {
    int temp_abs = -temp_raw;
    temp_int = - (temp_abs >> 4);
    temp_frac = temp_raw & 0x0F;
  }
  tempc = (double)temp_raw / 16.0;
  tempf = (tempc * 1.8) + 32.0;

  int tempf_int, tempf_tenths;
  tempf_int = int(tempf);
  if (tempf > 0) {
    tempf_tenths = tempf*10 - tempf_int*10;
  }
  else {
    tempf_tenths = tempf*10 + tempf_int*10;
  }

  Serial.print(count);
  Serial.print("  Temperature = ");
  Serial.print(temp_int);
  Serial.print(" ");
  Serial.print(temp_frac);
  Serial.print("/16 C (");

  Serial.print(tempf_int);
  Serial.print(".");
  Serial.print(tempf_tenths);
  Serial.println(" F)");

It's not elegant, but it gets the job done.  For my temperature logger, I leave the temperature as a scaled integer on the Arduino and convert it to deg Fahrenheit only after it's been uploaded to my laptop.
5  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: Please update OneWire page for DS18B20 on: April 21, 2008, 08:33:49 am
Quote
So the question is how do I write the C code to first pull out those two bytes, switch them around from LSB MSB to MSB LSB and then multiply that number by .0625?

In AVR C, an 'int' is a two-byte integer, and so you can combine the MSB and LSB of the temperature value into an 'int' value by saying
Code:
int rawtemp = (data[1] << 8) + data[0];
That's it - 'rawtemp' is now the signed temperature, multiplied by 16 (for the DS18B20).  To get floating point fahrenheit and centigrade temperatures, you would say
Code:
double tempc, tempf;
tempc = (double)rawtemp / 16.0;
tempf = (tempc * 1.8) + 32.0;
6  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: Please update OneWire page for DS18B20 on: January 02, 2008, 09:05:43 pm
Quote
The wiki is publicly editable, so feel free to create an account and update the pages yourself.
Thanks, I will.  (I'm not sure why I had the mistaken impression that editing privileges were restricted...)
7  Forum 2005-2010 (read only) / Bugs & Suggestions / Please update OneWire page for DS18B20 on: January 02, 2008, 05:35:38 pm
Hi,

I recently acquired a couple of DS18B20 temperature sensor chips from Sparkfun, in the hope of building a simple temperature logger.  In getting them to work on my Arduino, I found that the sample code on the OneWire wiki page fails for this chip, because the family code is this chip is 0x28, rather than 0x10.  Apart from this, the old sample code seems to work fine for the new chip.

Also, the link to the data sheet for the DS1820 on that page is broken, because the DS1820 has been completely replaced by the DS18S20 chip, now.  The URL for the DS18S20 datasheet is now http://datasheets.maxim-ic.com/en/ds/DS18S20.pdf  The data sheet for the DS18B20 chip available from Sparkfun is http://datasheets.maxim-ic.com/en/ds/DS18B20.pdf.  

I wanted to ask that you update the wiki page to reflect these changes.  Thanks!
8  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: maximum delay() is 32767ms ? on: February 19, 2008, 01:12:56 pm
Quote
Of course, without the macro, all four examples would fail,
That's not right, of course - the first example,

Code:
delay(60000);
works already.  It's just the second of my four examples that the macro would allow to work.
9  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: maximum delay() is 32767ms ? on: February 18, 2008, 04:26:01 am
Quote
I thought the subject of this thread was how to address overflow in the argument to the arduino delay function.
My main request when I started the thread to have the documentation improved, to explain more clearly how to use the delay() function correctly.  The docs still don't indicate what the type of the argument is.  A warning there about the perils of 16-bit arithmetic would also be pretty helpful.  

Quote
It seems to me that we help users with overflows in the arguments of functions like delay if the cast is implicitly done by calling the function through a macro. I wonder if you think that would be worthwhile.
I agree it would probably help most people avoid the mistake I made, and to that extent it might be worthwhile.  On the other hand, it doesn't help people understand what they're doing.  

My main objection to the macro, however, is that the way it works is a bit unclean.  The cast doesn't act on the argument as a whole, but depends on it being an arithmetic expression that can be modified before it's evaluated.  Usually, you try to avoid writing macros that work that way because they lead to code that fails mysteriously.  In this case, for example, the following cases do and don't work...
Code:
#define delay(_val) original_delay( (unsigned long) _val )
 
delay(60000);  //works
  
delay(60*1000);  //works

delay((60*1000));  // fails

unsigned long interval = 60*1000;
delay(interval);  // fails
So, the simplest and most common usages of the function would now work, but the reason why the last two examples fail would be hard to explain.  Just as C code, all four of my examples would ordinarily be expected to produce the same result, since all four delay() arguments evaluate to the same value when taken by themselves.  Of course, without the macro, all four examples would fail, but once you understood why, you'd have learned something useful and (hopefully) become a better C programmer.  
10  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: maximum delay() is 32767ms ? on: February 15, 2008, 05:20:55 pm
Quote
Casting the parameter in a macro to an unsigned long forces the compiler to do the entire calculation as a long in other platforms I have used. Are you saying that the suggestion to use a macro with the cast wont work here?
It might or it might not, depending on how the function is called.  In particular, it won't work unless the arithmetic is being done right there in the function call.  So, it would allow "delay(60*1000)" to work, but not, for instance, "int interval = 60 * 1000; delay(interval)".  
11  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: maximum delay() is 32767ms ? on: February 15, 2008, 04:02:23 pm
Quote
If the arduino distribution had delay declared as a macro (with the actual function renamed to _delay) then this would do the cast without the user knowing anything about it. It would look exactly the same as now but would operate as a long.
Again, the problem is with the arithmetic, not with the delay() function.  When you multiply the 16-bit signed integers 60 and 1000, you don't get 60000, but rather -5536.  (The biggest number you can represent as a 16-bit signed integer is 32767.)  Casting that result to an unsigned long doesn't get you 60000 back.  You need to do something to make sure the arithmetic is carried out using unsigned longs (32-bit integers) in the first place. It's not clear there's any convenient way to do that automatically, however.

A way of helping people avoid this mistake in the first place might be to provide special delay_*() functions for longer time units, and then document clearly what the maximum argument for each is.  If there were a delay_minutes() or delay_seconds() function, for instance, you wouldn't need to multiply 60*1000 to get the delay.  These special variants could easily be implemented as macros, e.g.,

#define delay_seconds (_val)   delay(1000L * (_val))

It doesn't fix the problem, of course, but ought to make it less likely that people get bitten by it.

12  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: maximum delay() is 32767ms ? on: February 13, 2008, 02:33:50 pm
Quote
Could some C++ strong typing, function overloading, and an extra version or three of delay() take care of this problem?  Maybe one delay() for each of the following input types: int, unsigned int, long, unsigned long.

As David explained, the problem is fundamentally that 60*1000 does not equal 60,000 here, because the result is an int (a signed 16 bit integer).  There's no way to catch that at the compiler level (that I can think of, anyway); you need to promote one or both of the constants to a long (32 bit integer) to get a result of 60000.  

The best you could do (I think) would be have a version of delay that accepted an int, and which would barf when given a negative delay.

13  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: maximum delay() is 32767ms ? on: January 19, 2008, 10:13:48 am
My bad.  I see now (from wiring.h) that the delay() function takes an unsigned long, so it should work for much longer delays than I was trying to use.  My mistake was multiplying a signed integer variable and a signed integer constant to get the delay time.  Making the variable unsigned long fixed things.

Sorry for the distraction...
14  Forum 2005-2010 (read only) / Bugs & Suggestions / maximum delay() is 32767ms ? on: January 18, 2008, 08:31:35 pm
From playing with it, it looks like the argument to the delay() function is treated as a signed int, making the maximum delay something like 32767 milliseconds.  Is that correct?  If so, it would be helpful to update the reference page for delay() to make this clear.  Currently there's no mention there of a maximum possible delay.  
 
I noticed this when I tried setting a delay of 60*1000 (one minute) and found that my sketch just hung at that point.  A delay of 30000 works, on the other hand.
 
Thanks.
15  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: how to avoid reset when starting serial monito on: January 21, 2008, 10:48:02 pm
Quote

No, I didn't have any luck searching for previous discussions  - thanks very much for the link!  The HUPCL trick sounds like it would do the trick for me, assuming I can ferret out what the necessary C incantations are...

For what it's worth, I'm building a simple event & temperature logger that sits around and collects data on an EEPROM.  Periodically, I want to make a serial connection to it to check the current state of the sensors, download the data, clear the data store -stuff like that.  It would be awkward to have it reset every time I made a serial connection.  (It's awkard now, having to leave it plugged into my laptop while it runs...)
Pages: [1] 2 3