Treppenlicht mit I2C

Jago:
Ach ja, gefährliche sache mit dem Halbwissen...
Könntest du mir den Link zur der ATiny I2C Bibliothek geben? Die ich im Kopf hatte arbeitet mit 1 bzw 8MHz....

Ich bin etwas verwirrt, die einzige Bibliothek die ich jetzt kenne ist die TinyWire. Da du keine Links aufrufen kannst, hier als Attachement. Wegen den 8Mhz, da hat der Autor folgendes unter Arduino Playground - USIi2c geschrieben:

By default the I2C master library (TinyWireM) is set to run at 1MHz. To run at 8MHz, #defines in USI_TWI_Master.h / .cpp must be changed. No changes are necessary for the I2C slave library (TinyWireS).

Ich hoffe das hilft dir ein wenig weiter, ich werde mich auch mal am Wochenende daran setzen :wink:

cu
Frank

TinyWireM.zip (14.6 KB)

TinyWireS.zip (8.36 KB)

Warum eigentlich große Distanzen mit einem nicht dafür ausgelegten Bussystem überbrücken? Dafür gibt es wesentlich flexiblere Busse wie z.B. CAN oder EIB... nur weil billiger, da schon integriert? ich glaube nicht dass man mit nem i²c-Bus ohne zusätzliche hardware auf Distanzen von mehreren Metern kommt, eher noch im cm-Bereich...

Nachtrag: Hab hier mal eine interessante Aufstellung der verschiedenen Busvarianten gefunden - unter anderem auch den I²C als Hausbus... anschleinend gibt es Treiber, die Kabellängen um die 100m ermöglichen.
http://www.mikrocontroller.net/articles/Hausbus#Vergleich_von_Hausbussystemen

Also, I2C ist für mein Projekt perfekt. Die kette ist maximal 3m lang und es werden ca. 15 Devices angesprochen. Wenn ich später den zweiten Stock dazuschalten will, kann ich den I2C Bus mit einem Treiber sowie 15 Devices ohne Probleme erweitern.

Also was soll gegen I2C sprechen? :wink:

Die maximale Leitungslänge hängt ja auch von der Geschwindigkeit des Busses ab. Ich denke, wenn man sich im Standard Mode (vgl. I2C-Spezifikationen, 100 kHz) bewegt, lassen sich auch mit Leitungslängen bis 5m realisieren.

So, hier jetzt das versprochene Beispiel (alles ungetest!!!):

//Für Arduino/Master:

#include <wire.h>

void setup () {
wire.begin();
}

void loop (){

byte Puffer [10];
byte i = 0;

Wire.beginTransmission (Slaveadesse); //Sensordaten vom Slave anfordern
Wire.write (Daten); //irgendein Wert den der Slave so versteht das er den Sensor auslesen soll
Wire.endTransmission

delay(5); //dem Slave Zeit geben um die Anfrage zu bearbeiten

Wire.requestFrom(Slaveadresse,2); //High und Low Byte vom Slave anfordern

while (Wire.available){
Puffer [i] = Wire.read();	//Byte auslesen, High und Low Byte müssen noch zusammengefügt werden 
}

//zweiten Slave auslesen

//Daten auswerten 

Wire.beginTransmission (Slaveadesse);
Wire.write (Daten); //irgendein Wert den der Slave versteht
Wire.endTransmission

delay (100);
}




//Für Slave / ATiny:

#include <TinyWireS.h>

void Setup () {
TinyWireS.begin (Slaveadresse);
}

void loop(){
byte Rec;
int Wert;

if (TinyWireS.available()){  //"Warten" bis Slave von Master angesprochen wird und egal 
			  //welcher Wert gesendet wird, der Slave schickt den Sensorwert zurück 
 Rec = TinyWireS.receive();
 Wert = analogRead(AnalogPin); //hier würde sich auch anbieten den 10bit-Wert auf 8bit Auflösung zu reduzieren
 TinyWireS.send(byte(Wert & 0xFF)); //Lowbyte senden
 TinyWireS.send(byte(Wert >> 8)); //Highbyte senden
}
}

@Marcus W: Was heißt hier nur weil billiger? Hier gehts ja nicht um ein paar Prozent günstiger! Zwischen I2C und EIB Geräten liegt einfach mal locker Faktor 10 bis 20! Bei CAN weis ich das nicht genau, was ich gesehen hatte war aber auch nicht wirklich im einstelligen Euro Bereich. Sicher hat alles seine Gründe, möchte da auch keine Diskusion in die Richtung starten. Wo ich dir natürlich recht geben muss, wenn man nur unter uC Daten überträgt kann man auch ander Bussysteme kostenneutral verwenden (oder man denkt sich selbst ein Protokoll aus ^^). Ich geh aber mal davon aus das da vielleicht auch mal andere I2C Geräte angeschlossen werden sollen :wink:

Jago:
So, hier jetzt das versprochene Beispiel (alles ungetest!!!):

Vielen Dank, das du daran noch gedacht hast. Ich werde das am Wochenende ausprobieren. laut "Wire" kann ich ja als Daten einfach nur einen integer Wert schicken, so wie ich es verstehe geht es ja nur darum dem Slave ein Signal zu schicken, das er den Wert des FSR rausrücken soll, richtig?

Aus der Diskussion wegen I2C halte ich mich mal raus, ich habe aber eine menge Artikel gelesen wo mit der entsprechenden Geschwindigkeit auf dem Bus durchaus mehrere 100 Meter Leitung möglich sind:

http://www.mikrocontroller.net/topic/71426

cu
Frank

Gerade bei diesem Link wird der I²C - wie von mir vorgeschlagen - auf CAN umgesetzt... noch dazu mit einer Wandlerplatine die pro Gerät knapp 20€ kostet :wink:

@xpix: Für mein Beispiel magst du recht haben das du nur irgendwas schicken musst. Aber bei deiner Anwendung wirst du konkrete Werte brauchen, da du dem ATiny sagen musst ob er nun den Sensor auslesen soll oder die LED schalten.
Ob die Funktion Wire.write den Datentyp Integer annimmt weis ich nicht, müsste man ggf untersuchen (zulässig sind char, byte und string/chararray mit Stringbegrenzer). I2C ist ursprünglich nur zum senden von einem Byte vorgesehen gewesen (Startbit Adresse Ack-Bit Datenbyte Stopbit ACK-Bit), später wurde dann das senden mehrer Bytes ohne vorangestellte Adresse hinzugefügt. Dh will wahrscheinlich die Funktion nur Bytes sehen, würde ich vermuten.

@Marcus: Mh, ganz sicher bin ich mir jetzt nicht wie du deinen Post meinst, mir wären 20€ aber zuviel (15 x 20€ = 300€ !!!!). Wenns mit dem I2C nicht klappen sollte würde ich aber dem nicht auf CAN gehen. Jedenfalls nicht wenn ich unter uC Daten übertragen will. Für ein Differenzsignal brauch ich zusätzliche Hardware, wenn ich meine Daten Manchestercodiert übertrage kann ich darauf verzichten und brauch keinen Cent mehr ausgeben.
Letztendlich hat xpix aber recht, die ganze Diskussion bringt nichts. Man müsste beide Lösungen ausarbeiten um zu sagen was nun besser ist, so ist doch alles nur Spekulation und Bauchgefühl(wobei natürlich ein paar Eckpunkte klar sind).

Vielleicht hat xpix am WE ein wenig Zeit und kann das ganze mal simulieren. Einfach mal 5m Leitung dazwischen und schauen ob es noch geht.

Hab übrigens noch was gefunden. Eine cat5-Leitung hat ca. 50pF je m und bei einer Busfrequenz von 100kHz sind 400pF zulässig. Damit beträgt die maximale Leitungslänge 4m, da xpix nur 3m braucht ist alles schön und schick. Störeinstrahlung wird ja wahrscheinlich nicht so das Thema sein, dh. denk mal das man auch Leitungen mit geringerer Kapazität findet (hab noch Stegleitung herumliegen wo die Leiter 5mm auseinander sind, denk mal die kommt unter 10pF).

Ich mein schon auch, dass 20€ zuviel dafür ist :slight_smile:

Jago:
@xpix: Für mein Beispiel magst du recht haben das du nur irgendwas schicken musst. Aber bei deiner Anwendung wirst du konkrete Werte brauchen, da du dem ATiny sagen musst ob er nun den Sensor auslesen soll oder die LED schalten.

Ich hab mal deine Beispiele so umgeschrieben, das sie durch den Compiler laufen. Ich muss mich noch ein wenig mit "Bit Mathe" beschäftigen :wink: Jedenfalls, die LED und Sensoren laufen alle getrennt auf jeweils einem I2C Device, deswegen ist das Signal erst einmal egal ... obwohl ... bei einem Device habe ich auch noch den Fotowiderstand, da muss er dann entscheiden. Sollte aber nicht so schwierig sein, das zu implementieren :wink:

Ich werd mal eine 3m (Pollin Flachbandkabel 4adrig) Leitung dazwischen hängen, mal sehen was passiert :wink:

@xpix: Wie gesagt, ungetestet... ...hab das Prog in Wordpad geschrieben.
Wenn du eine 4 adrige Leitung hast dann kannst du ja auch gleich mal 6m probieren. Würd mich nur mal so interessieren...
(aus kapazitätssicht ist die Verwendung der äußeren beiden Leiter garantiert auch sehr vorteilhaft)
Hab noch was gefunden, ist aber denk ich mal uninteressant für dich:
http://arduino.cc/forum/index.php/topic,68367.0.html

@Marcus: Na dann sind sich ja alle einig! Wunderbar! Weitermachen! 8)

Hallo zusammen

zu I2C und der Kabellänge kann ich einen kleinen Erfahrungsbericht beisteuern. In meinem "Newbi Projekt: Lüftersteuerung" bin ich vor dem Problem gestanden, einen I2C Themperatursensor anzusteuern, der auch ein paar meter entfernt vom UNO liegt. Try & Error hat mir keine Probleme aufgezeigt. Aktuell laufen durch den Kabelkanal neben den 2,5m Leitungen für den i2C auch noch 12V leitungen für die Lüfter und Messleitungen für 2 analoge Themperatursensoren.Alles 0,25mm²Elektroniklitze. Der Sensor lässt sich seit über 3 Monaten problemlos auslesen. Da dürften deine 3m kein Problem darstellen, noch dazu, wo du fast keine Leistung in der Nähe hast.Ich werde beim nächsten I2C Projekt meine alten CAT5 Kabel verbauen, dann haben die noch einen guten Zweck erfüllt (sind CAT5 STP) und ich werde (hoffentlich) keine Probleme bekommen.

Ich gebe den anderen Beitragsschreibern aber vollkommen Recht im Bezug auf die festgeschriebenen Spezifikationen und die Einhaltung der Grenzwerte.

Jago:
@xpix: Wie gesagt, ungetestet... ...hab das Prog in Wordpad geschrieben.

So, alles aufgebaut und was soll ich sagen, es funktionierte auf Anhieb. Hier mal ein Foto des Versuchsaufbau's und der Code für master und Slave. Auf dem Foto seht ihr den Arduino Nano sowie ein BlinkM Device sowie das I2C mit dem Drucksensor FSR 402. Das BlinkM hat in dem Aufbau erst einmal keine Funktion ... sobald man den Sensor betätigt bekommt man Werte bis 256 auf der Konsole.

//Für Arduino/Master:

#include <Wire.h>

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

void loop (){

  byte Puffer;
  byte i = 0;
  byte Daten = 1;
  int Slave = 4;

  Wire.beginTransmission(Slave); //Sensordaten vom Slave anfordern
  Wire.write(Daten); //irgendein Wert den der Slave so versteht das er den Sensor auslesen soll
  Wire.endTransmission();
  
  delay(5); //dem Slave Zeit geben um die Anfrage zu bearbeiten
  
  Wire.requestFrom(Slave, 2); //High und Low Byte vom Slave anfordern
  
  while (Wire.available()){
    Puffer = Wire.read();	//Byte auslesen, High und Low Byte müssen noch zusammengefügt werden 
    Serial.print("Receive: ");
    Serial.println(Puffer);
  }

  //zweiten Slave auslesen (in sub auslagern)
  //dritten Slave auslesen
  delay (100);
}
//Für Slave / ATiny:

#include <TinyWireS.h>

int Slave = 4; // Slave Adresse 
int AnalogPin = 2; // Port wo der FSB angeschlossen ist

void setup () {
  TinyWireS.begin (Slave);
}

void loop(){
  if (TinyWireS.available()){  //"Warten" bis Slave von Master angesprochen wird und egal 
    //welcher Wert gesendet wird, der Slave schickt den Sensorwert zurück 
    byte Rec = TinyWireS.receive();
    int Wert = analogRead(AnalogPin); 
    TinyWireS.send(byte(Wert & 0xFF)); //Lowbyte senden
    TinyWireS.send(byte(Wert >> 8)); //Highbyte senden
  }
}

Der Test mit den 3m sowie 6m kommt morgen dran, als Pullups konnte ich nur 5,2k einsetzen aber das sollte gehen.

Wie kann man eigentlich die Geschwindigkeit des Busses einstellen unter Wire?

Foto.JPG

Foto(1).JPG

Der Test mit den 3m sowie 6m kommt morgen dran, als Pullups konnte ich nur 5,2k einsetzen aber das sollte gehen.

Leider haben mich die Renovierung meines Hauses doch ein wenig mehr in Anspruch genommen, nun laut UPS kommen die ersten PCB's heute und dann werd ich den 6m Test etwas verschieben müssen. Aber es ist alles auf dem Weg :wink:

Na das freut mich doch das alles funktioniert hat!
Schöner Aufbau, mir gefällt vorallem der Gummi :smiley:
Wie man die Geschwindigkeit einstellt weis ich nicht. Vorgesehen ist in der Bibliothek nichts, soweit ich weis. Also müsste man mal ins Datenblatt schauen und das entsprechende Prescalerregister manipulieren (oder die Bibliothek umschreiben). Weis allerdings nicht wo das noch mit drin hängt. Könnt mir vorstellen das man da irgendeinen Timer mit beeinflusst und dann PWM, Millis oder micros "nicht mehr richtig" funktioniert.
5,2k sollte funktionieren, besser ist aber weniger (Stichwort umladen der Leitungskapazität). Ich bin garnicht sicher wo die Grenze war, glaube ein Kiloohm oder so.
Was meinst du mit PCB´s?
Das Problem mit dem Zeitmangel kenn ich, steck grad im Umzugsstreß....
MfG Jago

Jago:
Was meinst du mit PCB´s?

Nun, ich habe als erstes ein BlinkM Clone in Fritzing entworfen. Die habe ich dann als Gerberfiles an einen Leiterplattenhersteller: https://www.haka-lp.de geschickt und gestern bekommen. Aber wie das Leben so spielt, zwei Fehler waren in dem Entwurf. Ich hatte 2 Massen und der Reset Pin des Tinys war auf masse :wink: Aber nach brutalem umbiegen des Pin's lies sich das Teil ansprechen :wink: Mein größtes Problem, die Bohrungen der RGB LED waren einfach zu klein und ich muss mir jetzt was ausdenken um die gelieferten Leiterplatten doch noch nutzen zu können.

Hier mal mein geänderter Entwurf mit extra Buchsenleiste für die LED ...

Schema.GIF

Hallo,

so am Wochenende habe ich endlich zeit gehabt mich weiter um mein Projekt zu kümmern :wink: Die 13 Devices sind jetzt alle zusammen gelötet. Die falsche Routenführung hatte ich mit einem kleinen kabel gelößt. Der resetpin auf masse wurde durch brutales entfernen des pins an dem IC Sockel deaktiviert.

Um das I2C Problem etwas zu umgehen, habe ich mich entschlossen bei Reichelt ein 10 poliges Flachbandkabel nebst 2x5 Pfostensteckern zu kaufen. Die Signalleitungen haben dadurch immer eine Masseleitung zwischen sich und werden damit stabiler arbeiten.

Hier also ein paar Fotos von den kleinen Dinger :wink:

Foto 2.JPG

Foto 3.JPG

Ich weiss jetzt nicht ob jemand hier mitliest, aber ich mach einfach mal weiter.

Letzte Woche sind platinen aus Amerika und Deutschland angekommen. Die Amis waren fast genauso schnell, und lieferten mir die doppelte Anzahl an PCB's :wink: Um mal eine weitere Treppe mit mehr Power versorgen zu können, habe ich mal diese Version herstellen lassen:

Vorteil, ich kann Power RGB LED's oder auch RGB LED Streifen mit bis zu 40V/1.2A versorgen, dank der verbauten Darlington Transistoren. Die eagle Files habe ich so abgeändert, das statt SMD Widerstände normale genutzt werden können.

Hier der erste Testaufbau, ich habe eine 3W Power RGB China LED drangeschaltet, die maximal 1A zieht :wink: Gut, 13 Stufen a 1A ... na ja, man kann ja mal träumen. Mir ging es in erster Linie darum, auch RGB LED Streifen steuern zu können.

Später mehr über die andere Platine für den Analog Sensor.

Foto (2).JPG

wen die Story interessiert, ich mach hier weiter:

http://xpixer.blogspot.de/

Stairlight 1.0 :wink: