Forum: Mikrocontroller und Digitale Elektronik OneWire Problem DS2413


von Michi M. (mutzmutz)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,
ich mache gerade erste schritte mit dem OneWire Bus und hab heute den 
Temperaturbaustein DS18S20 beschäftigt, ging eigentlich ganz gut.
Nun wollte ich mit dem Adressierbarem Schalter DS2413 zwei LEDs (mit 
einem Pull up Widerstand und separaten spannungsquelle)  bei den beiden 
I/O’s    PIOA und PIO leds ein – und ausschalten.
Die 64Bit ID’s konnte ich ohne probleme auslesen, was ich noch nicht 
ganz begreife, wie ich die beiden I/O’s umschalten kann.
Ich habs folgendermassen versucht :
************************************************************************
#include <OneWire.h>

/* DS2413 switch chip i/o */

OneWire  ds(10);  // on pin 10

void setup(void) {
  Serial.begin(9600);
}

void loop(void) {
  byte i;
  byte present = 0;
  byte data[12];
  byte addr[8];

// search components
  if ( !ds.search(addr)) {
    Serial.print("No more addresses.\n");
    ds.reset_search();
    delay(250);
    return;
  }
 // just information for me
  Serial.print("Adress=");
  for( i = 0; i < 8; i++) {
    Serial.print(addr[i], HEX);
    Serial.print(" ");
  }
// crc check
  if ( OneWire::crc8( addr, 7) != addr[7]) {
      Serial.print("CRC is not valid!\n");
      return;
  }
  // check if DS2413
  if ( addr[0] != 0x3A) {
      Serial.print("Device is not a DS2413 family device.\n");
      return;
  }

// ??????????????? communication ???????????????

  ds.reset();
  ds.select(addr); // select component,

  ds.write(0xF5);         // PIO  write access
  ds.write(0xFC);        // write new output state
 ??????????????????????????????
 ??????????????????????????????

************************************************************************

und dort wo jetzt die kommunikation eigentlich geschehen soll, komm ich 
nicht mehr weiter, weil beim versuch einfach gar nichts passiert.
Kann mir jemand weiterhelfen?
bin um jegliche hinweise/tips froh!
Viele grüsse

von eProfi (Gast)


Lesenswert?

>  ds.write(0xF5);         // PIO  write access
>  ds.write(0xFC);        // write new output state



PIO Access Read  F5h
F5 ist der Befehl fürs Lesen, Du willst schreiben, also brauchst Du

PIO Access Write 5Ah

von Michi M. (mutzmutz)


Lesenswert?

stimmt, danke.
und dann sollte es funktionieren? ich begreife nicht ganz warum im 
datenblatt seite 17 (PIO ACCESS WRITE EXAMPLE) so viele schritte gemacht 
werden. schreiben, invertiert schreiben,2 mal lesen, wieder schreiben... 
?
versteht das jemand oder ist das ein etwas spezielles beispiel ?

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

Michi M. schrieb:
> schreiben, invertiert schreiben,

Das ist aus Sicherheitsgründen. Wenn beide Übertragungen nicht 
übereinstimmen, wird das PIO-Byte nicht angenommen.

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

Michi M. schrieb:
> ich begreife nicht ganz warum im
> datenblatt seite 17 (PIO ACCESS WRITE EXAMPLE) so viele schritte gemacht

Das gehört zum Übertragungsprotokoll:

Seite 16: PIO ACCESS WRITE (SUCCESS)

TX RESET
RX PRESENCE
TX SKIP ROM / MATCH ROM
TX PIOW (0x5a)
loop:
TX PIO-Output
TX PIO-Output (invertiert)
RX 0xAA (= Alles ok; Bei Fehlern 0xFF)
RX PIO STATUS BYTE

Zurück zu loop, wenn weitere Daten folgen; sonst RESET

PIO ACCESS WRITE
In an endless loop this command first writes new data to the PIO and 
then reads back the PIO status. This implicit read-after-write can be 
used by the master for status verification. A PIO Access Write can be 
terminated at any time with a 1-Wire Reset.

After the command code the master transmits a PIO Output Data byte that 
determines the new state of the PIO output transistors.

To protect the transmission against data errors, the master must repeat 
the PIO Output Data byte in its inverted form.

von Michi M. (mutzmutz)


Lesenswert?

alles klar, aber dann sollte folgendes funktionieren und ausreichen:

  ds.reset();
  ds.select(addr); // select component,
  ds.write(0x5A);         // PIO  write access
  ds.write(0xFC);        // write new output state

das flow chart im datenblatt "verlangt" unter anderem das empfangen 
eines Confirmation Bytes AAh, um die erfolgreiche kommunikation zu 
bestätigen. Ist das nötig oder wäre das lediglich eine 
sicherheitsmassnahme ?

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

Das reicht nicht, denn da fehlt der invertierte PIO-State.
Wenn das Datenblatt die Abfrage des Confirmation-Bytes "verlangt" sollte 
man es normalerweise auch so machen. Ob es wirklich nötig ist, musst Du 
selber ausprobieren.

Also:
  ds.reset();
  ds.select(addr);        // select component,
  ds.write(0x5A);         // PIO  write access
  ds.write(0xFC);         // write new output state
  ds.write(0x03);         // write inverted new output state

Es wird aber so sein, dass der 2413 in diesem Fall in einem 
Zwischenstatus hängt. Normalerweise holt ein Reset jedes 1-Wire-Slave in 
den Startzustand zurück. Ob es aber wirklich immer klappt, weiß ich 
nicht.

PS: Bei meinen Slaves wird das jedenfalls so gemacht.

von Michi M. (mutzmutz)


Lesenswert?

das heisst also er wiederholt solange bis ein Reset erfolgt?

Dann würde man sinnvollerweise einen automatischen Reset aulösen, wenn 
das Confirmation-Byte ==0xAAh ist ?

loop:
TX PIO-Output
TX PIO-Output (invertiert)

for ( i = 0; i < 7; i++) {  //RX 0xAA (= Alles ok; Bei Fehlern 0xFF)
    data[i] = ds.read();
  }
if(data==0xAA){
  ds.reset()
}

muss das statusbyte empfangen werden (so wie jetzt oben würde dies nicht 
mehr geschehen !?):

RX PIO STATUS BYTE

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

Michi M. schrieb:
> das heisst also er wiederholt solange bis ein Reset erfolgt?

So steht es im Datenblatt.

Michi M. schrieb:
> muss das statusbyte empfangen werden (so wie jetzt oben würde dies nicht
> mehr geschehen !?):

Kann sein, muss aber nicht.

Michi M. schrieb:
> data[i] = ds.read();

Damit liest Du aber keine Bits in data ein.
"data" ist hier wohl eher ein Array mit 8 Bytes - zumindest gehe ich mal 
davon aus; ansonsten geht das so nicht.

Michi M. schrieb:
> if(data==0xAA){

Das geht jedenfalls nicht, denn data ist ein Pointer auf das erste 
Arrayelement. Außer, der Compiler versteht bitoperationen und will sie 
so geschrieben haben.

Hmm, scheint mBed zu sein, oder?

von Michi M. (mutzmutz)


Lesenswert?

stimmt, hab mich vertan.. muss morgen schauen wie ichs schreiben muss. 
werde dann schreiben obs geklappt hat!
mBed sagt mir nichts... ich arbeite mit arduino, scheint wohl eine 
spezielle "entwicklungsumgebung" zu sein, da viele methoden und anderes 
schon vordefiniert bzw geschrieben sind...

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

Michi M. schrieb:
> Ich arbeite mit arduino

Ok, arduino kenne ich nur vom Namen her.
Scheint aber dem mbed-C(++) recht ähnlich zu sein.
Ich war von "normalem" C(++) ausgegangen.

von Michi M. (mutzmutz)


Lesenswert?

So lautet die "offizielle" Beschreibung für die Arduino Plattform :
Die Entwicklungsumgebung beruht auf Processing (einem Java-Dialekt) und 
Wiring (einem C-Dialekt)

:-)

von Michi M. (mutzmutz)


Lesenswert?

guten morgen,
habs jetzt geschafft, vielen
 dank Christian !! der codeabschnitt sieht jetzt folgendermassen aus :

ds.reset();// reset, wait for presence
  ds.select(addr);
  ds.write(0x5A); //PIO write access
  //loop until reset
  ds.write(0xFC); // write new output state : PIOB:ON, PIOA:ON
  ds.write(0x03); // write inverted new output
  for ( i = 0; i < 1; i++) {           // we need 1 byte
    data[i] = ds.read();
  }
  for(int i=0;i<1;i++){
    if(data[i]==170){// writing successful ?
      ds.reset();
    }
  }

von eProfi (Gast)


Lesenswert?

Es mag schon funktionieren, ist aber noch nicht sicher.
Außerdem sind die for-Schleifen überflüssig.

ungetesteter Vorschlag:

wdata=0xFC;
maxtry=5;do{
  ds.reset();// reset, wait for presence
  ds.select(addr);
  ds.write(0x5A);   //PIO write access
  ds.write( wdata); //write new output state : PIOB:ON, PIOA:ON
  ds.write(~wdata); //write inverted new output
  rdata=ds.read();} //reads 0xAA if successfull
while(rdata!=0xAA && --maxtry!=0)

if(maxtry){rdata=ds.read();printf("pin state is %x",rdata);}
else{printf("maxtry occured, wdata=%x rdata=%x",wdata,rdata);}

von Michael (c0d3z3r0)


Lesenswert?

Hallo,

sorry, dass ich so nen alten Thread ausgrabe.
Hat das schonmal jemand mit dem DS2406 probiert? Bei mir mag das 
irgendwie nicht klappen :(

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

DS2406 != DS2413
Mach einen neuen Thread auf und schände keine Leichen.

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.