Aller guten Dinge sind… 1-Wire Ultraschall Entfernungsmesser, ein neuer Ansatz

Eigentlich war ich mit der letzten Version (Link) schon sehr zufrieden, doch wurde ein IC eingesetzt welches nicht unbedingt günstig und gut beschaffbar war. Also habe ich das ganze Konzept noch einmal überarbeitet und es ist eine Lösung entstanden die gut funktioniert und günstig ist.

Die neue Platine sieht so aus …
1-Wire-US-Abstandsmesser-mit-Fake-DS18B20-PCB Aller guten Dinge sind... 1-Wire Ultraschall Entfernungsmesser, ein neuer AnsatzDa ich angesprochen wurde doch mal wieder Platinen zu entwickeln deren 1-Wire Bausteine direkt ohne Umwege (z.B. Loxberry) zu gehen mit der Loxone 1-Wire Extension nutzbar sind emuliere ich diesmal einfach einen DS18B20 Temperatursensor welcher zu allen Systemen kompatibel sein sollte die den 1-Wire Bus einsetzen.

Es gibt mit der OneWireHub Library eine gute Bibliothek die in der Arduino IDE eingebunden werden kann (link siehe weiter unten).

Wie funktioniert das alles jetzt?

Ein Mikrocontroller vom Typ ATMEGA168 oder ATMEGA328 ermittelt die Entfernung mit Hilfe z.B. eines HC-SR04 Moduls, dann wird ein echter DS18B20 abgefragt und so die aktuelle Umgebungstemperatur ermittelt.

Die Entfernung wird nun passend zur Temperatur korrigiert und es werden 2 emulierte DS18B20 auf den 1-Wire Bus geschaltet.

Der erste emulierte DS18B20 hat die ID des echten DS18B20 und liefert auch den aktuellen Temperaturwert, der zweite emulierte DS18B20 bekommt eine ID die sich aus teilen der des echten DS18B20 zusammensetzt, und liefert statt der Temperatur einfach die Entfernung in Metern zurück.

Die Angabe von Metern ist notwendig da der DS18B20 nur bis 125°C messen kann und somit nur Wert bis max 125 übertragen werden können (sollten) um die Kompatibilität zu gewährleisten.

Zum Auslesen des echten DS18B20 nutze ich die in der Arduino IDE verfügbare 1Wire Library, zur Abfrage des Ultraschall Sensor eine Library welche unter folgendendem Link zu finden ist.

Link: https://github.com/Martinsos/arduino-lib-hc-sr04

Die OneWireHub Library findet man unter diesem Link https://github.com/orgua/OneWireHub.

Zur Zeit habe ich die Schaltung nur auf dem Steckbrett aufgebaut und teste den Dauerbetrieb, es sieht jetzt nach 3 Tagen sehr stabil aus.

Weiter geht es…

Die ersten Platinen sind da und gelötet 🙂

Fertig aufgebaut sieht der Entfernungsmesser jetzt so aus…
1-Wire-US-Abstandsmesser-mit-Fake-DS18B20-fertig Aller guten Dinge sind... 1-Wire Ultraschall Entfernungsmesser, ein neuer AnsatzNachdem mein Dauertest erfolgreich war hier nun der Code für die Arduino IDE …

#include <HCSR04.h>
#include <OneWire.h>
#include <OneWireHub.h>
#include <DS18B20.h>  

int TriggerPin = 2;
int EchoPin = 3;
int OneWirePin = 10;
int OneWireHubPin = 14;
int LEDgreenPin = 18;
int LEDredPin = 19;
byte addr[8];

UltraSonicDistanceSensor distanceSensor(TriggerPin, EchoPin);

OneWire ds(OneWirePin);  

auto hub = OneWireHub(OneWireHubPin);

DS18B20 *ds18b20_temp;
DS18B20 *ds18b20_dist;

void setup () {
  pinMode(LEDgreenPin, OUTPUT);
  pinMode(LEDredPin, OUTPUT);
  
  digitalWrite(LEDgreenPin, 1);
  digitalWrite(LEDredPin, 0);
  
  if ( !ds.search(addr)) {
    ds.reset_search();
    delay(250);
    return;
  }

  if (OneWire::crc8(addr, 7) != addr[7]) {
      digitalWrite(LEDredPin, 1);
      digitalWrite(LEDgreenPin, 0);
      return;
  }
 
  if (addr[0] != 0x28) {
    digitalWrite(LEDredPin, 1);
    digitalWrite(LEDgreenPin, 0);
    return;
  } else {
    digitalWrite(LEDgreenPin, 1);
  } 
      
  ds18b20_temp = new DS18B20(DS18B20::family_code, addr[1], addr[2], addr[3], addr[4], addr[5], addr[6]);
  ds18b20_dist = new DS18B20(DS18B20::family_code, addr[6], addr[4], addr[2], 0x02, 0x09, 0x19);
  
  hub.attach(*ds18b20_temp);
  hub.attach(*ds18b20_dist);  
}

void dopoll() {
    hub.poll();

    if (hub.hasError()){
      digitalWrite(LEDredPin, 1);
    } else {
      digitalWrite(LEDredPin, 0);
    }
}

void loop () { 
  byte data[12];
  double distance=0;
  float temperature;
  int tmess=10000; 
  
  dopoll();
  
  if (tmess > 9999) {
    ds.reset();
    ds.select(addr);
    ds.write(0x44, 1);
    
    for (int i = 0; i < 800; i++){  
      delay(1);
      dopoll();
    }
 
    ds.reset();
    ds.select(addr);    
    ds.write(0xBE);
    
    for (byte i = 0; i < 9; i++) {
      data[i] = ds.read();
    }

    int16_t raw = (data[1] << 8) | data[0]; byte cfg = (data[4] & 0x60); if (cfg == 0x00) { raw = raw & ~7; } else if (cfg == 0x20) { raw = raw & ~3; } else if (cfg == 0x40) { raw = raw & ~1; } temperature = (float)raw / 16.0; ds18b20_temp -> setTemperature(temperature);    
    distance=distanceSensor.measureDistanceCm();
  
    dopoll();

    ds18b20_dist -> setTemperature(float(distance)/100);
   
    tmess=0;
  } else {
    tmess++;  
    delay(1);
  }
}

Folgende Bibliotheken müssen über den Bibliotheksverwalter installiert werden:
HCSR04 – Version 1.0.0
OneWire – Version 2.3.4
OneWireHub – Version 2.2.1

Ich benutze zum Programmieren einen AVR ISP mkII Progrrammer, die Fuses des ATMEGA müssen auf externen Quarz und Clk divide by 8 off eingestellt werden (das mache ich mit Bascom).

Danach kann man in der Arduino IDE einfach als Board das „Arduino Uno“ auswählen und das Programm kompilieren.

Nun kann man das Programm per „Sketch -> hochladen mit externem Programmer“ auf den ATMEGA328P übertragen. Es muss natürlich der korrekte Programmer unter „Werkzeuge -> Programmer“ ausgewählt sein.

Ich werde in Kürze aber auch fertig programmierte ATMEGA328P im Blog Shop anbieten.

Verlinke diesen Beitrag:

<a href="https://blog.thomasheldt.de/aller-guten-dinge-sind-1-wire-ultraschall-entfernungsmesser-ein-neuer-ansatz/">Aller guten Dinge sind… 1-Wire Ultraschall Entfernungsmesser, ein neuer Ansatz</a>

4 Gedanken zu „Aller guten Dinge sind… 1-Wire Ultraschall Entfernungsmesser, ein neuer Ansatz

  1. Markus

    Hallo Thomas,
    warum nutzt Du nicht die Hinter-Komma-Stellen um die Auflösung zu verbessern?
    D.h. z.B. 12.2°C = 122 cm
    Viele Grüße
    Markus

    Antworten
    1. Thomas H. Beitragsautor

      Hallo Markus,

      mache ich ja, der emulierte DS18B20 hat 3 Stellen nach dem Komma.

      Also z.B.: Die gemessene Entferunung ist 243cm dann gibt der emulierte DS18B20 2,43 als Wert raus.

      Gruß
      Thomas

      Antworten
  2. Markus

    Hallo Thomas,
    ist der Dauertest bereits erfolgreich abgeschlossen?
    Wo gibt es denn den Code für den Atmel?

    Grüße
    Markus

    Antworten
    1. Thomas H. Beitragsautor

      Hallo Markus,

      ja ich war zufrieden und der Code ist ab sofort im Beitrag veröffentlicht.

      Gruß
      Thomas

      Antworten

Schreibe einen Kommentar zu Thomas H. Antworten abbrechen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.