// DS2438_1 (Arduino)
//
// Illustrates an interface with a Dallas DS2438 Battery Monitor.
//
// Measures Temperature, Vad and Vdd 
//
// Displays to a serial LCD operating at 9600 baud.
//
// Arduino Board            DS2438
//
//                    +5 VDC
//                    |
//                   4.7K
// 8 ---------------- |---------------- DQ (term 8)
//
//                    +5 VDC ---------- Vdd (term 5)
//                    GRD ------------- GRD (term 1)
//
//                            --------- Vad (term 4)
//
// Tx ---------------------------- To Serial LCD (LCD #117)
//
// Peter H Anderson, Baltimore, MD, May 11, '07

#define V_AD 1
#define V_DD 0

int MeasTemperature_2438(int _1W_Pin);
int MeasADC(int _1W_Pin, int source);
int CalcRH(int Vad_100, int Vdd_100);

void OneWireReset(int _1W_Pin);
void OneWireOutByte(int _1W_Pin, byte d, byte strong);
byte OneWireInByte(int _1W_Pin);

void setup()
{
  int n, _1W_Pin;
  
  _1W_Pin = 8; 
  digitalWrite(_1W_Pin, LOW);  
  pinMode(_1W_Pin, INPUT);      // sets the digital pin as input (logic 1)
 
  Serial.begin(9600);
  delay(100);
  Serial.print("?B40"); // set backlight intensity
  delay(100);
  Serial.print("?f"); // clear LCD
  delay(100);
}

void loop()
{
  int  _1W_Pin, WordVal, SignBit, Tc_100, Vad_100, Vdd_100, RH_10, Whole, Fract;

  _1W_Pin = 8;     
 
 ///// Perfrom Temperature Measurement
  
  WordVal = MeasTemperature_2438(_1W_Pin); 
  SignBit = WordVal & 0x8000;
  if (SignBit)
  {
      WordVal = WordVal ^ 0xffff + 1; // take the twos comp
  }
  WordVal = WordVal / 8;
  Tc_100 = 3 * WordVal + WordVal / 8;  // 0.03125
  Whole = Tc_100 / 100;  // separate off the whole and fractional portions
  Fract = Tc_100 % 100;
  
  Serial.print("?f");  // clear LCD
  if (SignBit) // if negative
  {
    Serial.print("-");
  }  
  Serial.print(Whole);
  Serial.print(".");
  if (Fract < 10)
  {
     Serial.print("0");
  }
  Serial.print(Fract); 
  
  ///// Vad
  
  Vad_100 = MeasADC(_1W_Pin, V_AD);  
  Whole = Vad_100 / 100;  // separate off the whole and fractional portions
  Fract = Vad_100 % 100;
  
  Serial.print("?n");  // tab
    
  Serial.print(Whole);
  Serial.print(".");
  if (Fract < 10)
  {
     Serial.print("0");
  }
  Serial.print(Fract); 
 
  ///// Vdd
  Vdd_100 = MeasADC(_1W_Pin, V_DD);  
  Whole = Vdd_100 / 100;  // separate off the whole and fractional portions
  Fract = Vdd_100 % 100;
  
  Serial.print("?n");  // tab
    
  Serial.print(Whole);
  Serial.print(".");
  if (Fract < 10)
  {
     Serial.print("0");
  }
  Serial.print(Fract);   
  
  RH_10 = CalcRH(Vad_100, Vdd_100);
  
  Whole = RH_10 / 10;
  Fract = RH_10 % 10;
  
  Serial.print("?n");
  Serial.print(Whole);
  Serial.print(".");
  Serial.print(Fract);  
  
  delay(5000);      // 5 second delay.  Adjust as necessary
}
   
int MeasTemperature_2438(int _1W_Pin) 
{
     int a[9], v, tc_100, n;
     
     OneWireReset(_1W_Pin);
     OneWireOutByte(_1W_Pin, 0xcc, 0);  
     OneWireOutByte(_1W_Pin, 0x4e, 0);
     OneWireOutByte(_1W_Pin, 0x00, 0);  
     //OneWireOutByte(_1W_Pin, 0x00, 0);   // setup for VDD input
     
     OneWireReset(_1W_Pin);
     OneWireOutByte(_1W_Pin, 0xcc, 0);  
     OneWireOutByte(_1W_Pin, 0x44, 0);    // temperature
     
     delay(1000);

     OneWireReset(_1W_Pin);
     OneWireOutByte(_1W_Pin, 0xcc, 0);  
     OneWireOutByte(_1W_Pin, 0xb8, 0);
     OneWireOutByte(_1W_Pin, 0x00, 0);  // recall memory
     
     OneWireReset(_1W_Pin);
     OneWireOutByte(_1W_Pin, 0xcc, 0);  
     OneWireOutByte(_1W_Pin, 0xbe, 0);
     OneWireOutByte(_1W_Pin, 0x00, 0);  // read scratchpad beginning at zero
     
     for (n=0; n<9; n++)
     {
       a[n] = OneWireInByte(_1W_Pin); 
       //Serial.print(a[n]);
       //Serial.print("...?n");
       //delay(100);
     }  
       
     v = a[2] * 256 + a[1];    
     return(v); 
}

int MeasADC(int _1W_Pin, int source)
{
  int n, a[9], v;
  
  OneWireReset(_1W_Pin);
  OneWireOutByte(_1W_Pin, 0xcc, 0);  
  OneWireOutByte(_1W_Pin, 0x4e, 0);
  OneWireOutByte(_1W_Pin, 0x00, 0);   // setup for Vdd or A/D
  if (source == V_AD)
  {
      OneWireOutByte(_1W_Pin, 0x00, 0);  // Vad
  }
  else
  {
      OneWireOutByte(_1W_Pin, 0x08, 0);  // Vdd
  }     

  OneWireReset(_1W_Pin);
  OneWireOutByte(_1W_Pin, 0xcc, 0);  
  OneWireOutByte(_1W_Pin, 0xb4, 0);  // perform A/D
  delay(1000);  // wait for A/D to complete

  OneWireReset(_1W_Pin);
  OneWireOutByte(_1W_Pin, 0xcc, 0);  
  OneWireOutByte(_1W_Pin, 0xb8, 0);  
  OneWireOutByte(_1W_Pin, 0x00, 0);  // recall to scratchpad  

  OneWireReset(_1W_Pin);
  OneWireOutByte(_1W_Pin, 0xcc, 0);  
  OneWireOutByte(_1W_Pin, 0xbe, 0);  
  OneWireOutByte(_1W_Pin, 0x00, 0);  // read scratchpad
  
  for (n=0; n<9; n++)
  {
      a[n] = OneWireInByte(_1W_Pin); 
       //Serial.print(a[n]);
       //Serial.print("...?n");
       //delay(100);
  }  
       
  v = a[4] * 256 + a[3];    
  return(v); 
}  

int CalcRH(int Vad_100, int Vdd_100)
{
    int x, Vdd_10, RH_10;
    
    Vdd_10 = Vdd_100 / 10;
    x = 10 * Vad_100 / Vdd_10 - 16;
    RH_10 = 16 * x + x/10;
    return(RH_10);
}    
       
void OneWireReset(int _1W_Pin) // reset.  Should improve to act as a presence pulse
{
     digitalWrite(_1W_Pin, LOW);
     pinMode(_1W_Pin, OUTPUT); // bring low for 500 us
     delayMicroseconds(500);
     pinMode(_1W_Pin, INPUT);
     delayMicroseconds(500);     
}

void OneWireOutByte(int _1W_Pin, byte d, byte strong) // output byte d (least sig bit first). 
{
   byte n;
    
   for(n=8; n!=0; n--)
   {
      if ((d & 0x01) == 1)  // test least sig bit
      {
         digitalWrite(_1W_Pin, LOW);
         pinMode(_1W_Pin, OUTPUT); 
         delayMicroseconds(5);
         pinMode(_1W_Pin, INPUT);
         delayMicroseconds(60);
      }
      else
      {
         digitalWrite(_1W_Pin, LOW);
         pinMode(_1W_Pin, OUTPUT); 
         delayMicroseconds(60);
         pinMode(_1W_Pin, INPUT);
      }                 

      d=d>>1; // now the next bit is in the least sig bit position.
   }
   if(strong)
   {
       digitalWrite(_1W_Pin, HIGH); // One sec of strong +5 VDC
       pinMode(_1W_Pin, OUTPUT);
       delay(1000);
       pinMode(_1W_Pin, INPUT);
       digitalWrite(_1W_Pin, LOW);
   }
}

byte OneWireInByte(int _1W_Pin) // read byte, least sig byte first
{
    byte d, n, b;
    
    for (n=0; n<8; n++)
    {
        digitalWrite(_1W_Pin, LOW);
        pinMode(_1W_Pin, OUTPUT);
        delayMicroseconds(5);
        pinMode(_1W_Pin, INPUT);
        delayMicroseconds(5);
        b = digitalRead(_1W_Pin);
        delayMicroseconds(50);
        d = (d >> 1) | (b<<7); // shift d to right and insert b in most sig bit position
    }
    return(d);
}
RoboForex gives you opportunity to open your demo forex trading account at best spreads. . online roulette