Forum: Compiler & IDEs DS1820 alle paar sekunden eine Anfrage


von Matze K. (phytomed)


Lesenswert?

Moin,

ich habe eine Frage zum Temperatursensor ds1820.
Und zwar habe ich Code von Peter Dannegger verwendet,
allerdings evrändert, da ich die Daten nicht über UART ausgeben möchte.

Meine Anfrage sieht folgendermaßen aus:

    lcd_gotoxy(0,0);
    snprintf(lcd_buffer,16,"TEMP : %d", test);
    lcd_puts(lcd_buffer);
    start_meas();
    _delay_ms(500);
    temp = read_meas();
    lcd_gotoxy(0,1);
    if(temp !=0 ){
      snprintf(lcd_buffer,16,"%4d.%01dC",temp>>4,(temp << 12)/6553);
      lcd_puts(lcd_buffer);
    }

die abgeänderten Funktionen von Peter Dannegger,
welche die Kommunikation mit dem Sensor regeln


bit w1_reset(void){
  bit err=0;

  W1_OUT &= ~(1<<W1_PIN);
  W1_DDR |= 1<<W1_PIN;
  _delay_us(480);
  cli();
  W1_DDR &= ~(1<<W1_PIN);
  _delay_us(66);
  err = W1_IN & (1<<W1_PIN);      // no presence detect
  sei();
  _delay_us(414);
  if( (W1_IN & (1<<W1_PIN)) == 0 )    // short circuit
    err = 1;
  return err;
}


uchar w1_bit_io( bit b )
{
  cli();
  W1_DDR |= 1<<W1_PIN;
  _delay_us(1);
  if( b )
    W1_DDR &= ~(1<<W1_PIN);
  _delay_us(14);
  if( (W1_IN & (1<<W1_PIN)) == 0 )
    b = 0;
  _delay_us(45);
  W1_DDR &= ~(1<<W1_PIN);
  sei();
  return b;
}


uint w1_byte_wr( uchar b ){
  uchar i = 8, j;
  do{
    j = w1_bit_io( b & 1 );
    b >>= 1;
    if( j )
      b |= 0x80;
  }while( --i );
  return b;
}


uint w1_byte_rd( void ){
  return w1_byte_wr( 0xFF );
}


uchar w1_rom_search( uchar diff, uchar idata *id ){
  uchar i, j, next_diff;
  bit b;

  if( w1_reset() )
    return PRESENCE_ERR;      // error, no device found
  w1_byte_wr( SEARCH_ROM );      // ROM search command
  next_diff = LAST_DEVICE;      // unchanged on last device
  i = 8 * 8;          // 8 bytes
  do{
    j = 8;          // 8 bits
    do{
      b = w1_bit_io( 1 );      // read bit
      if( w1_bit_io( 1 ) ){      // read complement bit
  if( b )          // 11
    return DATA_ERR;      // data error
      }else{
  if( !b ){        // 00 = 2 devices
    if( diff > i ||
      ((*id & 1) && diff != i) ){
      b = 1;        // now 1
      next_diff = i;      // next pass 0
    }
  }
      }
      w1_bit_io( b );           // write bit
      *id >>= 1;
      if( b )          // store bit
  *id |= 0x80;
      i--;
    }while( --j );
    id++;          // next byte
  }while( i );
  return next_diff;        // to continue search
}


void w1_command( uchar command, uchar idata *id ){
  uchar i;
  w1_reset();
  if( id ){
    w1_byte_wr( MATCH_ROM );      // to a single device
    i = 8;
    do{
      w1_byte_wr( *id );
      id++;
    }while( --i );
  }else{
    w1_byte_wr( SKIP_ROM );      // to all devices
  }
  w1_byte_wr( command );
}

void start_meas( void ){

  if( W1_IN & 1<< W1_PIN ){
    w1_command( CONVERT_T, NULL );
    W1_OUT |= 1<< W1_PIN;
    W1_DDR |= 1<< W1_PIN;      // parasite power on

  }else{
    //uputsnl( "Short Circuit !" );
  }
}


uint read_meas( void ){

  uchar id[8], diff;
  uchar i;
  uint temp=0;

  diff = w1_rom_search( SEARCH_FIRST, id );

  if( diff == PRESENCE_ERR ){
    //temp=1;
    temp = 0;
  } else if( diff == DATA_ERR ){
    //temp = 2;
    temp = 0;
  } else if( id[0] == 0x28 || id[0] == 0x10 ){  // temperature sensor
    w1_byte_wr( READ );      // read command
    temp = w1_byte_rd();      // low byte
    temp |= (uint)w1_byte_rd() << 8;    // high byte
    if( id[0] == 0x10 )      // 9 -> 12 bit
      temp <<= 3;
  }
  return temp;
}

Allerdings "findet" er nur dann und wann die Temperatur,
meine Frage ist einerseits warum findet er die Temperatur nur manchmal.
Weiter würde ich gerne wissen, wie man "festlegen" kann, welcher Sensor 
von den mehreren am Bus angeschlossenen, man verwenden möchte.

Danke
Matthias

von Elektrikser (Gast)


Lesenswert?

Habe erstmal eine HW-Frage: Ist der Pull-Up-Widerstand (4,7k) von 
Datenleitung zu VCC eingebaut? Wenn nicht ist der 1-Wire ziemlich 
unberechenbar...

Gruß Elektrikser

von Matze K. (phytomed)


Lesenswert?

Ja einen solchen Widerstand habe ich eingebaut.
Ich glaube, dass er nicht immer einen Sensor findet,
meine Frage lautet deswegen, wie kann ich bestimmen
welchen Sensor ich auslesen möchte.

Dank
Matthias

von Elektrikser (Gast)


Lesenswert?

Am Anfang gar nicht. Zuerst werden die IDs ausgelesen (w1_rom_search, 
SEARCH_ROM) und nach der Größe der IDs sortiert, d.h. der mit der 
höchsten ID ist der erste. Erst danach kannst du eine Zuordnung machen.

Wenn dir der Code von Peda zu kryptisch ist, dann versuche es doch 
damit:

http://www.siwawi.arubi.uni-kl.de/avr_projects/#ds18x20demo

von Matze K. (phytomed)


Lesenswert?

Vielen Dank,

heisst das, dass ich nach einmaligem auslesen der IDs
die IDs für alle weiteren Durchläufe verwenden kann?

Danke
Matthias

von Elektrikser (Gast)


Lesenswert?

Ja, kannst du. Du musst einmal herausbekommen, welcher Sensor, welche ID 
hat.  Dann kann man einfach damit weiterarbeiten. Allerdings bei einem 
Sensor-Wechsel fängt das ganze wieder an...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.