Entwicklung einer 1wire-zu-WLAN-Bridge

Begonnen von hexenmeister, 18 Dezember 2015, 01:03:45

Vorheriges Thema - Nächstes Thema

habeIchVergessen

ich bin auch dabei.
Ein ESP-07 hat nur 512kB Flash. Gibt es noch mehr Unterschiede (kann auf die schnelle keine vernünftige Spec. finden)?

Kuzl

Zitat von: hexenmeister am 18 Dezember 2015, 08:07:47
Ah, interessant! Wie es die Erfahrung, läuft alles dauerhaft stabil?
Was verwendest Du als LevelShifter?
Code-technisch habe ich noch nichts, magst Du evtl. Dein Code offenlegen?
Kann ich gerne offenlegen, dauert aber bis Anfang nächster Woche, komm nicht eher nach Hause.
Als LevelShifter habe ich eine einfache Transistorschaltung verwendet, ich meine die wars:
(http://www.electro-tech-online.com/imgcache/4056-ST-5.jpg)

Verwendet habe ich den ESP-01 und an den übrigen Pin noch einen DHT22 drangehängt.
Bisher läuft das mit einem ca. 20m langen Bus ganz stabil, betrieben an einem Handynetzteil.

Gruß,
Kuzl

hexenmeister

Zitat von: Solala0815 am 18 Dezember 2015, 10:08:11
Habe hier im Haus einen Bus mit 30m ohne Protection, läuft seit 3 Jahren ohne größere Ausfälle.
So ähnlich läuft bei mir gerade auch. Allerdings will ich, für alle Fälle, den Schutz einbauen. Wenn aber jemand nicht will... Daher werde ich vermutlich Jumper zum Kurzschließen vorsehen.
Maintainer: MQTT_GENERIC_BRIDGE, SYSMON, SMARTMON, systemd_watchdog, MQTT, MQTT_DEVICE, MQTT_BRIDGE
Contrib: dev_proxy

hexenmeister

Zitat von: Kuzl am 18 Dezember 2015, 11:18:35
Kann ich gerne offenlegen, dauert aber bis Anfang nächster Woche, komm nicht eher nach Hause.

Keine Eile, so schnell bin ich auch nicht. Bis die Platinen fertig designt und gefertig sind... ;D

Zitat von: Kuzl am 18 Dezember 2015, 11:18:35
Als LevelShifter habe ich eine einfache Transistorschaltung verwendet, ich meine die wars:
Genau so habe ich mir auch vorgestellt. :)
Maintainer: MQTT_GENERIC_BRIDGE, SYSMON, SMARTMON, systemd_watchdog, MQTT, MQTT_DEVICE, MQTT_BRIDGE
Contrib: dev_proxy

roman1528

Moin. *interesse heuchel*

Feine sache das...
Auf ESD würde ich verzichten bzw. optional machen.
Als ESP würde doch eventuell auch der 07er reichen... (habe jetzt nicht 'drauf geachtet wieviele GPIO's gebraucht werden) Der ist kleine und hat eine IPX Buchse für eine externe Antenne (immer besser).
Die Platine würde ich dann per 5V micro-USB versorgen und nen kleinen SMD-3V3-Regler drauf setzen. Da gibt es welche die nur einen Kondensator als Zusatzbeschaltung brauchen.
Widerstände (auch wenn sie größer sind) würde ich 1206 SMD's nehmen. Lassen sich ganz klar besser löten. Auch für Laien.
Für den Anschluss der externen Komponenten vielleicht eine Federdruckklemme von DEGSON http://www.tme.eu/de/Document/4c1fa2b92914065be313ef72a9089f8e/dg390-5.0.pdf
1-Wire Busmaster: Gute Idee

reicht erstmal... bin für alles offen, habe 'ne Menge Zeit... einfach PM oder so^^

Gern setz ich mich auch ans Layout... habe allerdings nur SprintLayout da^^

Grüße^^

P.S. Der Link in meiner Signatur... nicht perfekt... aber im Grunde auch nur ein Prototyp :)
i3-10305T 4x3GHz;8GB RAM;250GB & 1TB NVMe:
FHEM 6.2;FTUI;8" Tablet's+Fully;NsPanelPro;HUE;ESPRGBWW;HM(CCU3);Duofern; ASC;MQTT(Tasmota);netatmo;SONOS;eBus;DbLog;XiaomiDevice;NUT;ModbusAttr

RPi3+: FHEM 6.2;I²C;GPIO;RFID;G-Tag;XiaomiBTLESens
RPi3: FHEM 6.2;DIY Relais-Board;I²C;GPIO;RFID;Photovoltaik

hexenmeister

#20
Zitat von: roman1528 am 19 Dezember 2015, 14:20:26
Auf ESD würde ich verzichten bzw. optional machen.
Als ESP würde doch eventuell auch der 07er reichen... (habe jetzt nicht 'drauf geachtet wieviele GPIO's gebraucht werden) Der ist kleine und hat eine IPX Buchse für eine externe Antenne (immer besser).
Die Platine würde ich dann per 5V micro-USB versorgen und nen kleinen SMD-3V3-Regler drauf setzen. Da gibt es welche die nur einen Kondensator als Zusatzbeschaltung brauchen.
Widerstände (auch wenn sie größer sind) würde ich 1206 SMD's nehmen. Lassen sich ganz klar besser löten. Auch für Laien.
Für den Anschluss der externen Komponenten vielleicht eine Federdruckklemme von DEGSON
Danke!
- ESD ist jetzt optional (zwei Lötbrücken)
- Ob 07er reicht, keine Ahnung, soll weniger Flash haben. Werden wir sehen. Pinkompatibel soll er ja sein.
- Platine hat jetzt MicroUSB-Buchse und Schraubklemme. 1W-Ausgang auch Klemmen. Die von TME sind nicht schlecht, lohnt sich aber die Bestellung derzeit nicht.
- Es sind zwei Regler drauf: 5V und 3,3V. Bei Versorgung über USB kann der 5V Regler samt zugehörigen 'Vogelfutter' unbestückt bleiben.
- 1206 Widerstände belegen irre viel Platz. Blieben erstmal 0805. Lassen sich auch noch gut löten (außerdem habe ich gerade eine Unmenge 0805er ;) ).
Das Löten wird übrigens für Laien an einer anderen Stelle ungemütlich - die Mosfets sind SOT23. Immerhin habe ich den winzigen PCA9306 eliminiert. :)
- Es sind jetzt alle (halbwegs) benutzbare GPIOs auf einer Leiste verfügbar
- Es sind zwei zusätzlichen Leisten für I2C-Erweiterungen
- Zum Testen ist ein optionaler DS18b20 vorgesehen


Weitere Vorschläge und Ideen?
Ansonsten hier ist die neue Version. Layouten mache ich, wenn der Schaltplan fest steht ;)
Wäre gut, wenn jemand einen Blick drauf wirft, ich baue zu gerne Fehler ein ;)

(http://forum.fhem.de/index.php?action=dlattach;topic=45853.0;attach=42400;image)

(http://forum.fhem.de/index.php?action=dlattach;topic=45853.0;attach=42390;image)
Maintainer: MQTT_GENERIC_BRIDGE, SYSMON, SMARTMON, systemd_watchdog, MQTT, MQTT_DEVICE, MQTT_BRIDGE
Contrib: dev_proxy

UweH

Hab ich ein Déjà-vu? Damals hat das hier kaum jemanden interessiert...mittlerweile rödelt das Teil seit 1 1/2 Jahren hier rum...

Gruß
Uwe

hexenmeister

Zitat von: UweH am 20 Dezember 2015, 09:59:33
Hab ich ein Déjà-vu? Damals hat das hier kaum jemanden interessiert...mittlerweile rödelt das Teil seit 1 1/2 Jahren hier rum...
Was soll ich sagen, war wohl die Zeit nicht reif ;D
Evtl. liegt aber auch an den Kosten, mit einem ESP kann man das Teil vermutlich wesentlich günstiger aufbauen.
Oder eben an dem anhaltenden ESP8266-Hipe  ;D
Maintainer: MQTT_GENERIC_BRIDGE, SYSMON, SMARTMON, systemd_watchdog, MQTT, MQTT_DEVICE, MQTT_BRIDGE
Contrib: dev_proxy

UweH

Die Idee ist von pah, er war der Zeit voraus, ich habe das nur für mich als Hutschienenmodell umgesetzt. Mittlerweile könnte man das Teil auch wesentlich günstiger zusammenschrauben, die Optokoppler hatte ich noch rumliegen, die kann man durch wesentlich preiswertere Modelle ersetzen oder eben einen Levelshifter. Aber so hat man einen Levelshifter mit galvanischer Trennung...
Viel Spaß weiterhin  :)

Gruß
Uwe

Kuzl

Hallo zusammen,

hier wie versprochen der Code von meinem Interface - wie gesagt ohne Busmaster da ich nur Temperatursensoren benutzen wollte:


// 1-Wire-Host with MQTT-Client

#include <stdio.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include "Client.h"
#include <EEPROM.h>

#include <OneWire.h>
#include <DallasTemperature.h>
#include <DHT.h>
#include <PubSubClient.h>
extern "C" {
  #include "user_interface.h"
  uint16 readvdd33(void);
}

#define HUMIDITY_SENSOR_PIN 2
#define ONE_WIRE_BUS 0


// --------- adjust following settings for radio
const char* ssid = "blablablablablablablablabla";
const char* password = "123456789";

// --------- settings for MQTT
char mqttBroker[] = "zbox";
int  mqttPort = 1883;

#define MQTTClientID "1Wire.0"
#define MQTT_USER ""
#define MQTT_PASSWORD ""

#define TOPIC_ClientID "1Wire"
#define TOPIC_LastWill  TOPIC_ClientID "/connected"
#define TOPIC_interval  TOPIC_ClientID "/interval"

#define TOPIC_HumidityState  TOPIC_ClientID "/DHT/humidity"
#define TOPIC_TemperatureState  TOPIC_ClientID "/DHT/temperature"
#define TOPIC_OneWireState  TOPIC_ClientID "/Temperatur_"
#define TOPIC_VddState TOPIC_ClientID "/Vdd"


// stati der mqtt statemachine
#define ST_INIT 0
#define ST_CONNECT 2
#define ST_CONNECTED 3


// mqtt callback handler
void mqttCallback(char* topic, byte* payload, unsigned int length);

WiFiClient ethClient;

//mqtt client verbindung definieren, samt callback
PubSubClient client(mqttBroker, mqttPort, mqttCallback, ethClient); // instanziierung ueber DNS Namen


DHT dht;

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

int interval = 300;

unsigned long dhtWaiter;
unsigned long oneWireWaiter;
unsigned long VddWaiter;
bool tempReq=false;
bool oneWireReq=false;
bool humReq=false;
bool vddReq=false;
float oneWireTemp[10];
int oneWireCount = 0;
float dht_temp;
float dht_hum;
float Vdd;

int MqState = 0;
unsigned long MqWaiter;
boolean callbackEnable=false;

char charBuffer[32];
char charBufferTopic[32];

// ------------------------
void setup() {
 
   Serial.begin(115200);   
   delay(5000);

   Serial.println("");Serial.println("startup..");
   
   // Connect to WiFi network
   WiFi.begin(ssid, password);
   Serial.println("Wifi Started");

   delay(1000);
   dht.setup(HUMIDITY_SENSOR_PIN); 
   delay(500);
   delay(500);
   sensors.begin();
   delay(500);
   oneWireCount = sensors.getDeviceCount();
   EEPROM.begin(2);
     
   interval = eepromReadInt(0);
   Serial.print("Interval stored in EEPROM: ");Serial.println(interval);
   if((interval == 0xFFFF) || (interval <= 0)) interval = 300;

  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
}

// ------------------------
// publish mit retain
boolean myPublish(char* topic, char* payload)
{
  client.publish(topic,(uint8_t*)payload,strlen(payload),true);
}

// ------------------------
// process DHT22
#define SHOW_MEASURE
void processDHT()
{
  // process after wait time or counter turn around
  if (millis() < dhtWaiter)
      return;
       
  dhtWaiter = millis() + max(interval * 1000,dht.getMinimumSamplingPeriod());
   
  dht.readSensor();
  if (dht.getStatus() != dht.ERROR_NONE)
  {
    Serial.print("result:");Serial.println(dht.getStatusString());
    return;
  }

  dht_temp = dht.getTemperature();
  dht_hum = dht.getHumidity();

  if (isnan(dht_temp)) {
    Serial.println("Failed reading temperature from DHT");
  }
  else{
    tempReq=true;
   
    #if defined(SHOW_MEASURE)
      Serial.println("");Serial.print("DHT_T: "); Serial.println(dht_temp);
    #endif
  }


  if (isnan(dht_hum)) {
    Serial.println("Failed reading humidity from DHT");
  }
  else{
    humReq=true;

    #if defined(SHOW_MEASURE)
      Serial.print("DHT_H: "); Serial.println(dht_hum);
    #endif
  }
}

// ------------------------
// process OneWire
void processOneWire()
{
  // process after wait time or counter turn around
  if (millis() < oneWireWaiter)
      return;
       
  oneWireWaiter = millis() + interval * 1000;
   
  if(oneWireCount == 0){
     Serial.println("No Device found on OneWire - Bus");
  }
  else{
     sensors.requestTemperatures(); // Send the command to get temperatures
   
     for(int i = 0; i < oneWireCount; i++){
        oneWireTemp[i] = sensors.getTempCByIndex(i); 
       
        if(oneWireTemp[i] == -127){
           Serial.print("Error Reading Temp from Sensor"); Serial.println(i); 
        }       
        #if defined(SHOW_MEASURE)
        Serial.print("OneWire Temp Index "); Serial.print(i); Serial.print(": "); Serial.println(oneWireTemp[i]);
        #endif
     }
     oneWireReq=true;
  }
}

// ------------------------
// process VDD
void processVDD()
{
  if (millis() < VddWaiter )
      return;
       
  VddWaiter = millis() + interval * 1000;

  Vdd = readvdd33() / 1000.0;
  vddReq=true;
 
  #if defined(SHOW_MEASURE)
     Serial.print("VDD: "); Serial.println(Vdd); Serial.println("");     
  #endif
}


// ---------------------------
// mqtt callback,after an external publish for subscribed items
void mqttCallback(char* topic, byte* payload, unsigned int length){
 
    int xlen;
    char buffer[20]; 
   
    Serial.print("callback starts with topic:");Serial.println(topic);
   
    xlen=min(length,sizeof(buffer)-2);
   
    memcpy(&buffer,payload,xlen);
    buffer[xlen]=0;
   
    Serial.print("compare to topic:");Serial.println(TOPIC_interval);
    if  (strcmp(topic, TOPIC_interval)  == 0) 
    {
       Serial.println("callback interval");
       
       String strpayload = String(buffer);
       interval = strpayload.toInt();
       
       if(interval <= 0) interval = 300;
       
       if(eepromReadInt(0) != interval){
         Serial.print("New Interval: "); Serial.println(interval);
          eepromWriteInt(0, interval);
          EEPROM.commit();
       }
    }
}

// ---------------------------
// processes the items to be published
void processMqttItems()
{
  char buffer[30];
  String strBuffer;
  String strOneWireTopic = "";
 
  if (humReq){
     humReq=false;
     strBuffer =  String(dht_hum);
     strBuffer.toCharArray(charBuffer,10);
     myPublish((char *)TOPIC_HumidityState,charBuffer); 
     Serial.print("update dht_hum: "); Serial.println(strBuffer);   
  }
 
  if (tempReq){
     tempReq=false;
     strBuffer =  String(dht_temp);
     strBuffer.toCharArray(charBuffer,10);
     myPublish((char *)TOPIC_TemperatureState,charBuffer); 
     Serial.print("update dht_temp: "); Serial.println(strBuffer);   
  }
 
  if (oneWireReq){
     oneWireReq=false;
     for(int i = 0; i < oneWireCount; i++){
       strBuffer =  String(oneWireTemp[i]);
       strBuffer.toCharArray(charBuffer,10);
       strOneWireTopic = TOPIC_OneWireState;
       strOneWireTopic = strOneWireTopic + i;
       strOneWireTopic.toCharArray(charBufferTopic,30);
       myPublish(charBufferTopic,charBuffer); 
       Serial.print("update OneWire Temp Index "); Serial.print(i); Serial.print(": ");Serial.println(strBuffer);
     }   
  }
 
  if (vddReq){
     vddReq=false;
     strBuffer =  String(Vdd);
     strBuffer.toCharArray(charBuffer,10);
     myPublish((char *)TOPIC_VddState,charBuffer); 
     Serial.print("update Vdd: "); Serial.println(strBuffer);   
  }
}
// -------------------------------

void processMQTT()
{

  int nextState=MqState;

  if (millis() < MqWaiter)
    return;

  if (MqState == ST_INIT){
    Serial.println("Init");
    client.disconnect();
    MqWaiter = millis() + 500;
    nextState = ST_CONNECT;
  }
 
else if (MqState == ST_CONNECT)
  {
    Serial.println("+Try to connect");
    Serial.print("ClientID:");Serial.println(TOPIC_ClientID);
   
    callbackEnable=false;
   
    // clientID, user,password,Will-Topic, Qos, Retain, will msg
    if (client.connect((char *)TOPIC_ClientID,(char *)MQTT_USER ,(char *)MQTT_PASSWORD,(char *)TOPIC_LastWill,1,1,(char *)"0")) 
    {
      Serial.println("connected");

      myPublish((char *)TOPIC_LastWill,(char *)"1");
     
      char buffer[30]; 
      String strBuffer =  String(interval);
      strBuffer.toCharArray(charBuffer,10);
      myPublish((char *)TOPIC_interval,charBuffer); 

      client.subscribe((char *)TOPIC_interval);
      callbackEnable=true;
     
      nextState = ST_CONNECTED;
    }
    else {
      Serial.println("not connected");
      nextState = ST_INIT;
    }
  }
 
  else if (MqState == ST_CONNECTED){
    // mqtt loop
    if ( ! client.loop())
    {
      Serial.println("disconnected");
      nextState = ST_INIT;
    }
    else {
      processMqttItems();
    }
  }

  if (nextState != MqState)
  {
    MqState = nextState;
    Serial.print("new state:");Serial.println(nextState);
  }


// -------------------------------
void eepromWriteInt(int adr, int wert) {
byte low, high;
  low=wert&0xFF;
  high=(wert>>8)&0xFF;
  EEPROM.write(adr, low); // dauert 3,3ms
  EEPROM.write(adr+1, high);
  return;
}

// -------------------------------
int eepromReadInt(int adr) {
byte low, high;
  low=EEPROM.read(adr);
  high=EEPROM.read(adr+1);
  return low + ((high << 8)&0xFF00);
}

// -------------------------------

void loop() {
 
  processDHT();
  processOneWire();
  processVDD();
  processMQTT();

}


Hierbei kann über den Topic "Interval" das Abfrageinterval einstestellt werden, das dann in den EEPROM gespeichert wird.

Viele Grüße,
Kuzl

PeMue

Zitat von: hexenmeister am 19 Dezember 2015, 23:59:18
- 1206 Widerstände belegen irre viel Platz. Blieben erstmal 0805. Lassen sich auch noch gut löten (außerdem habe ich gerade eine Unmenge 0805er ;) ).

Wäre gut, wenn jemand einen Blick drauf wirft, ich baue zu gerne Fehler ein ;)
Und bei mir rummaulen von wegen zu klein, kann ja keiner löten 8)
Ich schau's mir Anfang der Woche mal an, war leider heute morgen mit Papierkram beschäftigt und heute mittag war zu schönes Wetter ...
8) Soll ich auch die Bibliotheken kontrollieren *duckundweg*  8)

Gruß Peter
RPi3Bv1.2 rpiaddon 1.66 6.0 1xHM-CC-RT-DN 1.4 1xHM-TC-IT-WM 1.1 2xHB-UW-Sen-THPL-O 0.15 1x-I 0.14OTAU  1xCUNO2 1.67 2xEM1000WZ 2xUniroll 1xASH2200 3xHMS100T(F) 1xRFXtrx 90 1xWT440H 3xTFA30.3150 5xFA21
RPi1Bv2 LCDCSM 1.63 5.8 2xMAX HKT 1xMAX RT V200KW1 Heizung Wasser

frank

@hexenmeister

die adc beschaltung des esp mit r19/20 scheint nicht ok zu sein. wenn beide bestückt sind, liegen ca 1,65v an adc. erlaubt sind 1v max. zur nutzung wäre vielleicht sinnvoller r20 nicht nach vcc sondern zum adc pin deiner steckerleiste zu legen. siehe zb hier http://www.esp8266-projects.com/2015/03/internal-adc-esp8266.html
FHEM: 6.0(SVN) => Pi3(buster)
IO: CUL433|CUL868|HMLAN|HMUSB2|HMUART
CUL_HM: CC-TC|CC-VD|SEC-SD|SEC-SC|SEC-RHS|Sw1PBU-FM|Sw1-FM|Dim1TPBU-FM|Dim1T-FM|ES-PMSw1-Pl
IT: ITZ500|ITT1500|ITR1500|GRR3500
WebUI [HMdeviceTools.js (hm.js)]: https://forum.fhem.de/index.php/topic,106959.0.html

hexenmeister

Zitat von: frank am 20 Dezember 2015, 21:08:25
die adc beschaltung des esp mit r19/20 scheint nicht ok zu sein. wenn beide bestückt sind, liegen ca 1,65v an adc. erlaubt sind 1v max. zur nutzung wäre vielleicht sinnvoller r20 nicht nach vcc sondern zum adc pin deiner steckerleiste zu legen. siehe zb hier http://www.esp8266-projects.com/2015/03/internal-adc-esp8266.html
Moin! Danke für die Korrektur.
Ich gebe zu, das mit ADC habe ich auf Anfrage hier im Forum eingebaut und auf die Werte gar nicht geschaut. Sollten natürlich nicht beide 10K sein. Du meinst r19 nicht auf VCC sondern auf Pinleiste?, R20 ist ja GND? Zusätzlich? Oder statt? Was hat man davon, habe die Idee irgendwie noch nicht begriffen...
Maintainer: MQTT_GENERIC_BRIDGE, SYSMON, SMARTMON, systemd_watchdog, MQTT, MQTT_DEVICE, MQTT_BRIDGE
Contrib: dev_proxy

hexenmeister

Zitat von: PeMue am 20 Dezember 2015, 19:04:48
Und bei mir rummaulen von wegen zu klein, kann ja keiner löten 8)
Ich schau's mir Anfang der Woche mal an, war leider heute morgen mit Papierkram beschäftigt und heute mittag war zu schönes Wetter ...
8) Soll ich auch die Bibliotheken kontrollieren *duckundweg*  8)
Lag daran, dass ich zu dem Zeitpunkt keine 0805er hatte. Jetzt habe ich die hunderterweise. Müssen weg ;)
Mache Dir keinen Stress, ich habe auch nicht zu viel zeit. Es wird fertig, wenn es fertig ist ;)
Aufgrund der Erfahrung, sollten die Libs nicht unberücksichtigt blieben ;)

Maintainer: MQTT_GENERIC_BRIDGE, SYSMON, SMARTMON, systemd_watchdog, MQTT, MQTT_DEVICE, MQTT_BRIDGE
Contrib: dev_proxy

hexenmeister

Zitat von: Kuzl am 20 Dezember 2015, 18:55:58
hier wie versprochen der Code von meinem Interface - wie gesagt ohne Busmaster da ich nur Temperatursensoren benutzen wollte:

Vielen Dank, lege ich schon mal beiseite! for future use :)

So, ich muss erstmal etwas hardware bestellen, die Schaltung kann ich gerade nicht mal komplett auf dem Breadboard aufbauen.
Maintainer: MQTT_GENERIC_BRIDGE, SYSMON, SMARTMON, systemd_watchdog, MQTT, MQTT_DEVICE, MQTT_BRIDGE
Contrib: dev_proxy