2008年11月12日 星期三

Arduino 及RS485

RS485 Circuit = Success

自製紅外線接收及發射器

Dallas Semiconductor's 1-Wire interface

DS18B20


/* ds18B20_test<br /><br />  Test utility to configure resolution and read temp from the Dallas Semi 18B20 <br />  one-wire digital temp sensor.<br />  <br />  datasheet: http://datasheets.maxim-ic.com/en/ds/DS18B20.pdf<br /><br />  Derived from sample code at http://www.arduino.cc/playground/Learning/OneWire<br /><br />*/<br /><br />#include <OneWire.h><br /><br />#define BAUDRATE 9600<br />#define TEMPSENSOR 3  // arduino i/o port connected to the ds18B20<br />//#define DEBUG         // uncomment for verbose output<br /><br />/* some defines to make more legible checks into data read from the device <br /> *   (see the DS18B20 datasheet for more detail)<br /> */ <br />#define TEMP_LSB 0<br />#define TEMP_MSB 1<br />#define TH_REG 2<br />#define USERBYTE_1 2<br />#define TL_REG 3<br />#define USERBYTE_2 3<br />#define CONFIG_REG 4<br />#define CRC 8<br /><br />OneWire ds(TEMPSENSOR); <br /><br />void setup() {<br />  Serial.begin(BAUDRATE);<br />}<br /><br />/* convert celsius to fahrenheit<br /> *<br /> *   takes: float<br /> * returns: float<br /> */<br />float c2f(float cel) {<br />  return (cel * (9.0/5.0)) + (float)32;<br />}<br /><br />/* read temp from DS18B20 sensor using one-wire protocol */<br />void loop() {<br /><br />  byte i;<br />  byte present = 0;<br />  byte data[12];<br />  byte addr[8];<br /><br />  int temp_c_int;<br />  float temp_c_frac;<br />  float temp_c;<br />  float temp_f;<br />  int test_bit;<br />  int set_bit;<br />  int resolution_floor;<br />  float expon;<br />  <br />  if ( !ds.search(addr)) {<br />      ds.reset_search();<br />      return;<br />  }<br /><br />  /* print the address - might be useful for non-debug mode if you have<br />   *   >1 devices on the bus<br />   */<br />#ifdef DEBUG<br />  Serial.print("R=");<br />  for( i = 0; i < 8; i++) {<br />    Serial.print(addr[i], HEX);<br />    Serial.print(" ");<br />  }<br />#endif<br /><br />  if ( OneWire::crc8( addr, 7) != addr[7]) {<br />      Serial.print("CRC is not valid!\n");<br />      return;<br />  }<br /><br />  if ( addr[0] != 0x28) {<br />      Serial.print("Device is not a DS18B20 family device.\n");<br />      return;<br />  }<br /><br />  /* modify scratchpad register to set temp sampling resolution */<br />  ds.reset();<br />  ds.select(addr);    <br />  ds.write(0x4E);          // write scratchpad (starts at byte 2)<br />  // note:  set high/low temp alarms by changing the next two values <br />  ds.write(0x4B);    // default value of TH reg (user byte 1)<br />  ds.write(0x46);    // default value of TL reg (user byte 2)<br />  // uncomment one of the following<br />  //ds.write(0x7F);    // 12-bit sampling resolution (default)<br />  //ds.write(0x5F);    // 11-bit<br />  //ds.write(0x3F);    // 10-bit<br />  ds.write(0x1F);    // 9-bit<br /><br />  ds.reset();<br />  ds.select(addr);<br />  ds.write(0x44,1);    // start conversion, with parasite power on at the end<br /><br />  delay(1000);     // maybe 750ms is enough, maybe not<br />  // we might do a ds.depower() here, but the reset will take care of it.<br /><br />  present = ds.reset();<br />  ds.select(addr);    <br />  ds.write(0xBE);          // Read Scratchpad<br /><br />  if (!present) {<br />    Serial.print("ERROR: selected device not present\n");<br />    return;<br />  }<br />  <br />  for ( i = 0; i < 9; i++) {           // we need 9 bytes<br />    data[i] = ds.read();<br />#ifdef DEBUG<br />    Serial.print(data[i], HEX);<br />    Serial.print(" ");<br />#endif<br />  }<br /><br />  if (data[8] != OneWire::crc8(data,8)) {<br />    Serial.print("ERROR: CRC didn't match\n");<br />    return;<br />  }<br />  <br />  /* print raw bytes from which we'll extract temp data */<br />#ifdef DEBUG <br />  Serial.print("[MSB:");<br />  Serial.print(data[TEMP_MSB],BIN);<br />  Serial.print(" LSB:");<br />  Serial.print(data[TEMP_LSB],BIN);<br />  Serial.print("] ");<br />#endif<br />  <br />  /* compute the degrees in celcius / integer part */<br />  temp_c_int = 0;<br />  <br />  /* The measured temp is spread across two bytes of the returned data.<br />   *  The integer part of the temp value is spread across the least 3 significant<br />   *  bits of the most significant byte (MSB) and the most significant 4 of <br />   *  the LSB.  Here we shift those 7 bits into their proper place in our<br />   *  result byte. <br />   *<br />   * note: could do this with 2 bit-shift / mask operations, alternatively<br />   */<br />  set_bit = 6;<br />  for (test_bit = 2; test_bit >= 0; test_bit--) {<br />    temp_c_int |= ( ((data[TEMP_MSB] & (1 << test_bit)) >> test_bit) << set_bit );<br />    set_bit--;<br />  }<br />  for (test_bit = 7; test_bit >= 4; test_bit--) {<br />    temp_c_int |= ( ((data[TEMP_LSB] & (1 << test_bit)) >> test_bit) << set_bit );<br />    set_bit--;<br />  }<br /><br />#ifdef DEBUG<br />  Serial.print(temp_c_int,DEC);<br />#endif<br /><br />  /* compute the fractional part */<br /><br />  /*  first figure out what resolution we're measuring in - varies between 1 and 4 bits<br />   *    after the decimal (based on the contents of the CONFIG_REG byte):<br />   *        bit 6 == 0 && bit 5 == 0 --> 9-bit resolution (ignore 3 least sig bits)<br />   *        bit 6 == 0 && bit 5 == 1 --> 10-bit resolution (ignore 2 least sig bits)<br />   *        bit 6 == 1 && bit 5 == 0 --> 11-bit resolution (ignore 1 least sig bits)<br />   *        bit 6 == 1 && bit 5 == 1 --> 12-bit resolution   <br />   */<br />  if ((data[CONFIG_REG] & (1 << 5)) > 0) {        <br />    if ((data[CONFIG_REG] & (1 << 4)) > 0) {      // bits 6 and 5 are set<br />      resolution_floor = 0;<br />    } else {                                      // bit 6 is set, 5 is clear<br />      resolution_floor = 1;<br />    }<br />  } else {<br />    if ((data[CONFIG_REG] & (1 << 4)) > 0) {      // bits 6 is clear, 5 is set<br />      resolution_floor = 2;<br />    } else {                                      // bit 6 and 5 are clear<br />      resolution_floor = 3;<br />    }<br />  }    <br /><br />  temp_c_frac = 0;<br />  for (test_bit = 3; test_bit >= resolution_floor; test_bit--) {<br />    if ((data[TEMP_LSB] & (1 << test_bit)) > 0) {<br />      expon = test_bit - 4; // will be negative<br />      temp_c_frac += pow(2,expon);<br />    }<br />  }<br />#ifdef DEBUG<br />  Serial.print(" ");<br />  Serial.print(temp_c_frac * 10000,DEC);<br />#endif<br /><br />  /* put it all together */<br />  temp_c = (float)temp_c_int + temp_c_frac;  <br /><br />  if ((data[TEMP_MSB] & (1 << 7)) > 0) {   // the temp is negative<br />    temp_c *= -1;<br />  }<br /><br />  temp_f = c2f(temp_c);<br />  <br />  Serial.print(" Cx10k=");<br />  Serial.print(temp_c * 10000,DEC); // Serial.print truncates after the decimal pt<br />  Serial.print(" Fx10k=");<br />  Serial.print(temp_f * 10000,DEC);<br />  <br />  Serial.print("\n");  <br />}<br />

2008年11月10日 星期一

ProtoLab Wiki

realtime clock, microseconds, etc.

Arduino Forum - realtime clock, microseconds, etc.
realtime clock, microseconds, etc.

presice timing with arduino

Arduino Forum - presice timing with arduino

int analogPin = 3;     // potentiometer wiper (middle terminal) connected to analog pin 3
                       // outside leads to ground and +5V
int val = 0;           // variable to store the value read
int sta = 0;           // sta 0 =low 1 = high;
int counter = 0 ;        // conter
int time = 0 ;     
int i = 1;
int ii = 0;
int sample = 50;
void setup()
{
  Serial.begin(115200);          //  setup serial
}

void loop()
{
 //  Serial.print(i);
   val = analogRead(analogPin);    // read the input pin 
  
   if (val >= 400){
     if((i-ii) >= 5){
  //   Serial.print(" ");
  //   Serial.print(val);    // debug value  
   ii = i ; 
   counter++ ;
   }

  // sta = 1;
  
   }else{
 // Serial.println(10);
  // sta = 0;
   //  delay(1000);  1 sec
}
//Serial.println();
delay(50); // delay 0.05 sec

if (i >= 400) {        // passs 20 sec;
 time = counter * 3 ;
 Serial.println(time);
  i = 1;
  ii = 1;
  counter = 0;
 }
i++;
}