Forum: Mikrocontroller und Digitale Elektronik I2C Kommunikation zwischen Atmega128 und Drucksensor


von Daniel F. (mcnanuk)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe Verständnisschwierigkeiten, was eine I2C Kommunikation angeht.
Ich habe das noch nie gemacht, und stehe nun wahrscheinlich wie alle vor 
den selben Startschwierigkeiten.

Ich habe ein Board von Display3000 und in diesen steht: Ich zitiere:

>Unser Board D072 bietet an den Ports D0 und D1 den direkten Anschluss an >einen 
I²C-Bus.
>Ein I²C Bus muss immer mittels Pullup-Widerständen auf ein definiertes 
>Spannungsniveau angehoben werden. Wenn das Board D072 als Masterboard >fungieren 
soll und es im System noch keine weiteren I²C Bus-Teilnehmer mit 
>Pullup-Widerständen gibt, so können diese direkt im D072-Board eingelötet 
>werden. Das folgende Foto zeigt die beiden >bereits beschrifteten
>Positionen (blaues Rechteck), an denen jeweils ein 4,7 KOhm bis 10 KOhm-
>Widerstand (SMD Bauform 603) eingelötet werden kann. Die Lötpads stehen >dort zur 
Verfügung. Mehr ist (außer Software) für I²C nicht notwendig.

Zusätzlich verwende ich einen Drucksensor, der laut Datenblatt als Slave 
funktioniert. Ist das nun ein I2C Bus Teilnehmer mit Pull-Up 
Widerständen? Ode rmuss ich auf meinem Board wie beschrieben die beiden 
Widerstände einlöten?
Wenn ich den Bus richtig verstehe, dann Agiert mein Atmega128 als Master 
und sendet ein START an den Slave... dann kommt eine Folge von Befehlen, 
bis der Master das STOP Sendet. Richtig?

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Daniel F. schrieb:

> Zusätzlich verwende ich einen Drucksensor, der laut Datenblatt als Slave
> funktioniert. Ist das nun ein I2C Bus Teilnehmer mit Pull-Up
> Widerständen?

Der hat keine Pull-Ups eingebaut. Du brauchst also eigene Pull-ups am 
I2C Bus.

> Oder muss ich auf meinem Board wie beschrieben die beiden
> Widerstände einlöten?

Die eigenen Pull-ups kannst du dort einlöten; du musst es aber nicht. 
Du kannst deinen I2C-Bus auch so aufbauen, dass die Pullups anderswo 
sitzen. Das ist interessant, wenn du nicht auf dem Display SMD löten 
magst/kannst. In der I2C Spezifikation von Philips (NXP) ist ein 
Diagramm drin.

> Wenn ich den Bus richtig verstehe, dann Agiert mein Atmega128 als Master
> und sendet ein START an den Slave... dann kommt eine Folge von Befehlen,
> bis der Master das STOP Sendet. Richtig?

Die richtige Reihenfolge und Inhalte der I2C-Kommandos stehen in den 
Datenblättern der jeweiligen Bausteine. Also Datenblätter wälzen.

Ich würde zunächst nur den einfachsten I2C Slave (Drucksensor) 
anschliessen und die Ausgabe zum Debuggen z.B. über UART/RS232 ausgeben. 
Wenn diese Kommunikation dann fehlerfrei steht, dann den nächsten I2C 
Slave (Display) an den Bus anschliessen.

von Daniel F. (mcnanuk)


Lesenswert?

Auch wenn die Frage blöd erscheint, ich habe Schwierigkeiten mit dem 
Wort Pullups.
Was stell ich mir denn unter einem Pullup vor. ? ich habe bisher nur mit 
dem STK 500 gearbeitet. Nun scheint die ganze Sache etwas komplizierter 
zu werden.

Was ich momentan im Kopf habe:

Ich verbinder die Pins des Drucksensors mit den beiden Pins auf dem 
Board, und löte jeweils einen Widerstand dazwischen, oder dahinter ?

Dann schaue schreibe ich meinen Code(Das ist der Teil den ich mir 
zutraue) und alles ist gut :)
RS232 steht mir leider nicht zur Verfügung zum debuggen.


Bin ich völlig falsch?

von Stefan B. (stefan) Benutzerseite


Lesenswert?

> Ich verbinder die Pins des Drucksensors mit den beiden Pins auf dem
> Board, und löte jeweils einen Widerstand dazwischen, oder dahinter ?

Weder noch.

THE I2C-BUS SPECIFICATION VERSION 2.1 JANUARY 2000
http://www.nxp.com/acrobat_download2/literature/9398/39340011.pdf

Ein Pull-Up Widerstand zieht eine Signalleitung (oder einen µC-Pin) auf 
einen HIGH Pegel. Bei der Kommunikation brauchen dann Master/Slave die 
Leitungen nur zeitweise auf LOW zu ziehen; sie brauchen selbst aber 
keinen Saft zu liefern, damit die Leitung wieder auf HIGH geschaltet 
wird. Weil nur an einer Stelle Saft eingespeist wird (bei den Pullups) 
braucht man sich auch keine Sorgen wg. Überlastung zu machen, wenn die 
Pull-Ups richtig (=> Spezifikation) dimensioniert sind.

Dein Bus sieht so aus:
Vcc    o------------+---+------------
                    |   |
                    #   # Pull-Up
                    #   #
                    |   |
µC SDA o------------+----------------
                        |
µC SCL o----------------+------------

GND    o-----------------------------

von Daniel F. (mcnanuk)


Lesenswert?

Danke, jetzt wo ich es vor mir sehe wird es klarer.

Also müssen die Widerstände (hier in deiner Skizze als Rauten) die 
richtige Dimension besitzen, was wohl laut Datenblatt vom 
Boardhersteller etwa 4,7 KOhm bis 10 KOhm beträgt?

diese werde ich dann auf einem extra Board verlöten, da mir diese SMD 
Lötstellen einfach viel zu klein sind, und ich eher etwas kaputt mache, 
als dass ich hier weiter komme.

von MWS (Gast)


Lesenswert?

Je nach Länge der Verbindungsleitung zwischen Sensor und µC und abhängig 
von der Busgeschwindigkeit kann es ausreichen, die internen Pullups des 
µC zu setzen. Mit was programmierst Du ? Bascom ? Dann reicht's im Code 
die I2C Portpins (die des HW TWI) anzugeben und ein I2CInit zu 
schreiben, das aktiviert die µC internen Pullups.

von Daniel F. (mcnanuk)


Lesenswert?

Ich programmiere mit WinAVR.

Die Länge zwischen Sensor und Controller ist bei ca 5 cm :)
Zum Board geht eine etwa 5,2 V starke Spannung.

von Tim (Gast)


Lesenswert?

Bei 5cm ist es egal wo die Pullups sitzen.
Hauptsache sie sind drin.

von Daniel F. (mcnanuk)


Lesenswert?

Im Datenblatt ist an Pin 1 des Sensors mein Vc angeschlossen. Dort 
schliesse ich meine 5V an, die das System bereitstellt.
Die Pins 5 und 8 sind die beiden Leitungen SCL und SDA. Diese Verbinde 
ich nun mit den beiden Pins auf dem Board D0 und D1.

Wo baue ich aber nun die Pullups, bzw die beiden Widerstände ein, wenn 
ich sie nicht auf das Board löten will.

Wenn ich das richtig sehe, dann muss ich:


Vcc    o------------+---+------------
                    |   |
                    #   # Pull-Up
                    #   #
                    |   |
µC SDA o------------+---------------- SDA Sensor
                        |
µC SCL o----------------+------------ SCL Sensor

GND    o----------------------------- GND Sensor


verbinden.
Mein Board bekommt eine Spannung von 5,3 V aus einer externen 
Spannungsquelle. Leider kann ich auf dem Board selbst die Spannung nicht 
abgreifen, was bedeutet ich muss mir eine kleine Platine zusammenlöten.
Diese Spannungsquelle verwende ich auch um meinen Sensor zu versorgen. 
Kann ich einfach an diese Leitung die Pullups setzen ?

Vcc extern ---+----Vcc an µC
              |
              +---------+------+---------Vcc an Sensor
                        |      |
                        #      # Pull-Up
                        #      #
                        |      |
                   -----+---------------SDA Sensor
                               |
                     ----------+--------SCL Sensor

Also so stell ich es mir vor.

Verzeiht meine doofen Fragen, aber ich bin wirklich unsicher, und will, 
bevor ich auch nur einen Lötpunkt setze sicher sein, dass ich es richtig 
verstanden habe.

von Stefan B. (stefan) Benutzerseite


Angehängte Dateien:

Lesenswert?

Wo gibt es denn so etwas, dass du an Vcc und GND nicht dran kommst? Was 
ist denn das für eine seltsame Atmega128-Platine, gibt es da ein Link, 
Foto oder Schaltplan? (Bildformate beachten!). Hast du einen 
ISP-Anschluss auf der Platine? Wenn ja kannst du GND und Vcc dort 
bekommen (natürlich wenn der ISP-Programmieradapter abgezogen ist).

> ich nun mit den beiden Pins auf dem Board D0 und D1.

Meinst du PD0 und PD1 wie im Bild im Anhang?

Die Zeichnung ist so OK, wenn auf dem Atmega128 Board mit Vcc = Vextern 
gearbeitet wird. Manche µC-Boards haben aber einen Spannungsregler um 
z.B. von 5V auf 3.3V Vcc zu kommen. In diesem Fall müssten wir über 
deinen Aufbau und Pegelwandler noch mal reden! Und: Vergiss die GND 
Leitung nicht!

von Daniel F. (mcnanuk)


Angehängte Dateien:

Lesenswert?

Danke,
stimmt ISP ... hab ich nicht dran gedacht :) Da steck aber auch grade 
der Programmer dran.
Ich habe grade nochmal geschaut, und jetzt plötzlich taucht da eine 
Steckplatz für eine 5V verbindung auf... ich könnt schwören die war eben 
noch nicht da :)

Naja okay jetzt weiß ich bescheid.

Jetzt noch eine Frage zu den Widerständen die zu wählen sind. Der 
hersteller gibt in seinem Handbuch ja 4,7 bis 10 kOhm an. Wie kommt er 
denn auf diese Zahlen. Sind die auf die 5 Volt bezogen, oder geht er von 
einer anderen Spannung aus? Ohmsches Gesetz ?

Einen richtigen Schaltplan gibt es leider nicht zu dem Board. Nur ein 
Excel Sheet, welche Pins wie belegt sind, und ein ziemlich ausführliches 
Handbuch. Allerdings wie schon im Eingangspost nur so erwähnt.
Die beiden Widerstände sollen auf die beiden Lötbrücken links unter dem 
Chrystal gelötet werden.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Daniel F. schrieb:

> Jetzt noch eine Frage zu den Widerständen die zu wählen sind. Der
> hersteller gibt in seinem Handbuch ja 4,7 bis 10 kOhm an. Wie kommt er
> denn auf diese Zahlen. Sind die auf die 5 Volt bezogen, oder geht er von
> einer anderen Spannung aus? Ohmsches Gesetz ?

Ja, 5V.

Die Pull-ups haben einen Einfluß auf den Strombedarf der Schaltung, was 
die I2C-Geräte an Strom schlucken müssen einerseits und die Steilheit 
der Signale andererseits. Die genannten Werte sind in der Praxis 
bewährte Werte.

Im Detail nachzulesen hier ab S. 41-42

>> THE I2C-BUS SPECIFICATION VERSION 2.1 JANUARY 2000
>> http://www.nxp.com/acrobat_download2/literature/93...

von Daniel F. (mcnanuk)


Angehängte Dateien:

Lesenswert?

Ich hab den Sensor jetzt verdrahtet, bekomm aber über den I2C kein 
Signal.

Jetzt will ich mal die Hardware überprüfen. (siehe Bild)

Ist das so richtig verlötet? Ich bekomme Spannung und GND vom Atmega128, 
und hinten gehen SCL und SDA an den Port D (PD0 und PD1).

Wenn das stimmt, werde ich mich um die Software kümmern, aber zuerst 
einen Hardwarefehler ausschliessen.


Wenn ich den Sensor unter Spannung setze und den Analogen Ausgang VOut 
messe, habe ich 4,1V was den Spezifikationen entspricht.

Auch sind beide Ausgänge SCL und SDA auf knapp 5 V (genau 4,92 V)

Also funktionieren tut der Sensor wohl, und die Pullups scheinen auch zu 
passen.
Vielleicht kann ja jemand mal draufschauen, sorry wegen dem Bild, besser 
kanns mein Handy nicht :)

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Sieht richtig aus.

von Daniel F. (mcnanuk)


Lesenswert?

leider hängt sich die Software beim Start Befehl schon auf... nutze die 
Libary von Peter Fleury.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Welche Software? Ich sehe keine Software.

> nutze die Libary von Peter Fleury

http://homepage.hispeed.ch/peterfleury/avr-software.html

Welche Sensoradresse benutzt du (1111000xb obacht: 7 Bits!)?

Also als Argument für die i2c_start... Funktion:
0xF0 fürs Lesen?
0xF1 fürs Schreiben?

von Daniel F. (mcnanuk)


Lesenswert?

>#define SQ277  0x78 // 1111000xb.

>#define I2C_READ    1
>#define I2C_WRITE   0

ist meine Sensoradresse.
1
if((i2c_start(SQ277+I2C_READ))== 0) //Slave bereit zum lesen?
2
    {
3
      byte1 = i2c_readAck();                   
4
      byte2 = i2c_readNak(); 
5
      i2c_stop();
6
    }else{
7
      LCD_Print("I2C Error", 1, 60, 2, 1, 1, red, black);
8
    }

Verbunden ist
SLC --- PD0
SDA --- PD1,

Beide Pins sind unbelegt, und als Ausgang definiert.

von Route_66 (Gast)


Lesenswert?

Hallo!

wird die PIN-Nummerierung denn nicht IMMER als Draufsicht angegeben?

Das "Foto" des Musteraufbaus ist aber von unten.

von Route_66 (Gast)


Lesenswert?

Entschuldigung. falsch geguckt.

von Daniel F. (mcnanuk)


Lesenswert?

ich habe drauf geachtet, dass es stimmt :) Die Pins am Sensor selbst 
sind richtig belegt.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Daniel F. schrieb:
>>#define SQ277  0x78 // 1111000xb.
>
>>#define I2C_READ    1
>>#define I2C_WRITE   0
>
> ist meine Sensoradresse.

Das kann ich aus dem Datenblatt nicht nachvollziehen. Ich bin der 
Ansicht:

>> Welche Sensoradresse benutzt du (1111000xb obacht: 7 Bits!)?

Start        Slaveadresse    R/W-Bit
                 7 Bit        1 Bit
            MSB         LSB
             1 1 1 1 0 0 0      0         => Schreiben
             1 1 1 1 0 0 0      1         => Lesen

Also für die Kombination slave address + R/W Bit als Argument für die 
Library:

#define SQ277  0xF0
#define I2C_READ    1

> Verbunden ist
> SLC --- PD0
> SDA --- PD1,
> Beide Pins sind unbelegt, und als Ausgang definiert.

Nee, lass die auf Eingang. Auf Ausgang setzen wird aber das Hardware TWI 
Modul des Atmega128 nicht stören.

Machst du auch irgendwo in deinem Programm einmal das erforderliche 
i2c_init()?

von Daniel F. (mcnanuk)


Lesenswert?

Danke ....init rufe ich auf, das passiert mir pro Woche nur einmal dass 
ich das vergesse.

Ich werd das mal versuchen. Muss mich da aber erst reinlesen. Ich hab 
das mit der Adresse wohl falsch verstanden.


Huch wiso gelöscht ? Die Formel stimmt doch für 16 Mhz ...

von Stefan B. (stefan) Benutzerseite


Lesenswert?

> Huch wiso gelöscht ? Die Formel stimmt doch für 16 Mhz ...

Habe ich auch gemerkt und deshalb habe ich meinen Murksbeitrag gelöscht. 
Ich hatte 16000000/100000 = 16 gerechnet :-)

von Daniel F. (mcnanuk)


Lesenswert?

Wer ohne Fehl werfe den ersten ... naja oder so :)

von Daniel F. (mcnanuk)


Lesenswert?

Die Idee war gut, nur leider hat es nix gebracht.
Selbes Problem.

Die einfachste Lösung wäre: Falsche Adresse. Aber wie soll ich das 
herausfinden?


Das ist meine Main Methode.
1
#define SQ277  0xF0      // device address of SQ277, see datasheet
2
int main( void )
3
{
4
  unsigned char buffer[30];  
5
6
  uint16_t adcval;
7
  uint16_t hoehe = 0;
8
  //adcFlag 0=adc anzeigen, 1 = nicht anzeigen.
9
  int adcFlag = 0;
10
   
11
     
12
13
  init_adc();
14
  
15
  LCD_Init();  // caution: this also defines SPI for the display and also PortB (all ports but MISO are output)   
16
17
  DDRC = 0b11111111; // Alle auf Ausgang
18
  
19
20
    KEY_DDR &= ~ALL_KEYS;                // konfigure key port for input
21
    KEY_PORT |= ALL_KEYS;                // and turn on pull up resistors
22
 
23
  TCCR0 = (1<<CS02)|(1<<CS00);      // divide by 1024
24
    TIMSK |= 1<<TOIE0;        // enable timer interrupt
25
   
26
27
  
28
  delay_ms(1000);
29
       LCD_Cls(black);  
30
 
31
    sei();
32
  
33
  
34
35
  LCD_Print("Innendruck:", 1, 100, 2, 1, 1, green, black);
36
  LCD_Print(itoa(messeInternenDruck(),buffer,10), 1, 120, 2, 1, 1, green, black);
37
   LCD_Print("   mbar", 20, 120, 2, 1, 1, green, black);
38
39
40
  LCD_Print("Höhe:", 1, 160, 2, 1, 1, green, black);
41
  LCD_Print(itoa(hoehe,buffer,10), 50, 160, 2, 1, 1, green, black);
42
   LCD_Print("ft", 110, 160, 2, 1, 1, green, black);
43
44
45
46
  while(1){
47
48
    
49
50
51
  //Taste links
52
  if( get_key_press( 1<<KEY5 ) ) {
53
    
54
    Orientation = Portrait180;
55
    LCD_Print("Taste5", 1, 40, 2, 1, 1, yellow, black);
56
57
    LCD_Print(" mbar", 20, 60, 2, 1, 1, yellow, black);
58
    
59
    uint8_t byte1;//= 0b00001111;
60
    uint8_t byte2;//= 0b00000011;
61
    int16_t int1;
62
  
63
      i2c_start(SQ277+I2C_READ);
64
      LCD_Print(itoa(12,buffer,10), 1, 60, 2, 1, 1, yellow, black);
65
      i2c_init(); 
66
      byte1 = i2c_readAck();                   
67
          byte2 = i2c_readNak(); 
68
      i2c_stop();
69
    /*if((i2c_start(SQ277+I2C_READ))== 0) //Slave bereit zum lesen?
70
    {
71
      LCD_Print(" mbar123", 20, 60, 2, 1, 1, red, black);
72
      i2c_start(SQ277+I2C_READ);
73
      byte1 = i2c_readAck();                   
74
          byte2 = i2c_readNak(); 
75
      i2c_stop();
76
    }else{
77
      LCD_Print("I2C Error", 1, 60, 2, 1, 1, red, black);
78
    }*/
79
    
80
81
    int1=((int16_t)(byte1) << 8) | (int16_t)(byte2) ;
82
    LCD_Print(itoa(int1,buffer,10), 1, 60, 2, 1, 1, yellow, black);
83
84
85
    }
86
87
88
89
  
90
91
92
  }
93
}
94
95
//  Enhanced delay-routine (wait) as as the standard delay routine (_delay_ms) is not able to delay
96
//  more than 17 ms maximum as of the used 8-bit-timer (depending on used crystal)
97
void delay_ms(uint16_t period)   //delay routine (milliseconds)
98
{
99
  for(unsigned int i=0; i<=period; i++)
100
    _delay_ms(1);
101
}

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Bei Listings muss ich im Moment pausieren :-)
Beitrag "Üble Anzeige eines Listings im Beitrag"

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Ich versuch's doch :-)
Ist vollkommen out-of-sequence

      // 1. Initialisierung (außerhalb while(1))
      i2c_init();

      ...

      // 2. Auslesen (innerhalb while(1))
      if ( i2c_start(SQ277+I2C_READ) == 0 )
      {
        byte1 = i2c_readAck();
        byte2 = i2c_readNak();
        i2c_stop(); // Einsparbar, macht i2c_readNak() mit

        // 3. Ausgeben
        int1 = ((int16_t) byte1 << 8) | byte2;
        LCD_Print(itoa(int1,buffer,10), 1, 60, 2, 1, 1, yellow, black);
        LCD_Print(" mbar123", 20, 60, 2, 1, 1, red, black);
      }
      else
      {
        LCD_Print("I2C Error", 1, 60, 2, 1, 1, red, black);
      }

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Ich denke, dass die Berechnung int1 => Druck in mbar noch nicht stimmt. 
Du musst die digitalen Werte noch auf den Messbereich des Sensors 
umrechnen.

Im Datenblatt steht:

SQ277...U... (unidirectional devices)
DIGITAL PERFORMANCE CHARACTERISTICS

Characteristics        Min. Typ. Max. Unit
Zero pressure offset   03D7 0666 08F6
Full scale span (FSS)4 63D6 6666 68F5

und

Full Scale Span (FSS) is the algebraic difference between the output 
signal for the highest and lowest specified pressure.

Und weil Min. Typ. und Max. angegeben sind, ist die Umrechnung vom 
jeweiligen Einzelexemplar des Sensors abhängig, d.h. du brauchst eine 
Kalibrierung mit einem unabhängigen Druckmesser um die Formel 
aufzustellen.

Wenn du dazu Fragen hast, gib die vollständige Bezeichnung deines 
Sensors an, damit man die Antworten am konkreten Modell festmachen kann.

von micha (Gast)


Lesenswert?

@Daniel

Sorry, kein wirklicher Beitrag zum Thema, aber wo hast du den Sensor 
bezogen und wie viel hat er gekostet? Ich suche im Moment ein paar 
Drucksensoren und habe eigentlich nur die Freescale MXP5700 gefunden. 
Die sind aber analog und I2C wäre nett.

Michael

von Daniel F. (mcnanuk)


Lesenswert?

Stefan B. schrieb:
> Wenn du dazu Fragen hast, gib die vollständige Bezeichnung deines
> Sensors an, damit man die Antworten am konkreten Modell festmachen kann.

ne dazu noch nicht. Es ist immer noch so, dass der Sensor nix überträgt, 
und das Programm hängenbleibt beim Startbefehl....

Ich bin völlig ratlos.

Kalibrierung etc ist klar. Dafür sind schon alle vorkehrungen getroffen.

@ Micha: Es ist der SQ277 - 1FHU von Sensor Tronics, und wurde mir über 
dritte als Muster zur Verfügung gestellt. Ich glaube der kostet auch ne 
ganze Menge wenn man Ihn kaufen müsste.

von Michael H. (ripper)


Lesenswert?

Daniel F. schrieb:
> Stefan B. schrieb:
>> Wenn du dazu Fragen hast, gib die vollständige Bezeichnung deines
>> Sensors an, damit man die Antworten am konkreten Modell festmachen kann.
>
> ne dazu noch nicht. Es ist immer noch so, dass der Sensor nix überträgt,
> und das Programm hängenbleibt beim Startbefehl....

Das selbe Problem habe ich mit der Library auch, ich versuche einen 
Ultraschallsensor anzusprechen(Mit ATMEGA32). Bisher hat mir keiner 
helfen können... Ich werde es halt mit Assembler probieren, da gibt es 
hier im Forum eine gute I²C-Master Funktion.

Mfg Michael

von Daniel F. (mcnanuk)


Lesenswert?

Hier nochmal mein kompletter Code. Ob das Ergebnis nun stimmt oder 
nicht, sei mal dahingestellt, Fakt ist, es geht gar nix.

Ich beschreibe mal was genau passiert:
Auf dem Display erscheint mbar
sonst geschieht nix, weder geht die Fehlermeldung hoch, noch schreibt er 
weitere Zeilen auf das Display.

Ich habe gestern festgestellt, dass D0 und D1 vom Board anderweilig 
belegt sein können. Das sind zwei der 6 Tasten die am Board angebracht 
sind.
Die Tasten die an D0 und D1 angeschlossen sein können, waren, bzw habe 
ich an G0 und RESET angeschlossen. Somit sind die beiden Pins wieder 
frei. Oder irre ich mich ? Muss ich da softwaretechnisch irgendwas 
beachten ?
Ich habe ein Porttestprogramm für das Display, und dort wird bei keiner 
Taste D0 oder D1 erreicht.


Wenn die Slave Adersse falsch wäre, müsste dann die i2c_start-Methode 
nicht 0 als result geben ?
In der twimaster.c habe ich auch die Frequenz von 4 Mhz auf 16 Mhz 
gesetzt. Daran kann es also auch nicht liegen.



Also wenn irgendjemand eine Idee hat, wie ich den Fehler eingrenzen 
kann, wäre ich sehr dankbar. Irgendwas läuft doch da komplett falsch. 
Also als ob mein Board die beiden Pins gar nicht kennt.

Der Sensor wird vom Board mit Spannung und Masse versorgt, kann es hier 
ein Problem geben? Wenn ich am analogen Ausgang messe, dann bekomm ich 
di richtigen werte, das habe ich geprüft.
1
#include <stdlib.h>
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
#include <avr/pgmspace.h>
5
#include <util/delay.h>
6
#include <string.h>
7
#include "glcd-Display3000-211.h"
8
#include "i2cmaster.h"
9
10
11
#define SQ277  0xF0      // device address of SQ277, see datasheet
12
 
13
#define F_CPU 16000000UL
14
15
 
16
volatile uint8_t key_state;                                // debounced and inverted key state:
17
                                                  // bit = 1: key pressed
18
volatile uint8_t key_press;                                // key press detect
19
20
21
int main( void )
22
{
23
  unsigned char buffer[30];  
24
25
  
26
  LCD_Init();  // caution: this also defines SPI for the display and also PortB (all ports but MISO are output)   
27
28
  i2c_init();
29
30
31
  TCCR0 = (1<<CS02)|(1<<CS00);      // divide by 1024
32
    TIMSK |= 1<<TOIE0;        // enable timer interrupt
33
34
  LCD_Cls(black);  
35
 
36
37
  
38
  while(1){
39
40
    
41
    Orientation = Portrait180;
42
43
    LCD_Print(" mbar", 20, 60, 2, 1, 1, yellow, black);
44
    
45
    uint8_t byte1;//= 0b00001111;
46
    uint8_t byte2;//= 0b00000011;
47
    int16_t int1;
48
49
50
    // 2. Auslesen (innerhalb while(1))
51
      if ( i2c_start(SQ277+I2C_READ) == 0 )
52
      {
53
        byte1 = i2c_readAck();
54
        byte2 = i2c_readNak();
55
        i2c_stop(); // Einsparbar, macht i2c_readNak() mit
56
57
        // 3. Ausgeben
58
        int1 = ((int16_t) byte1 << 8) | byte2;
59
        LCD_Print(itoa(int1,buffer,10), 1, 60, 2, 1, 1, yellow, black);
60
        LCD_Print(" Test", 20, 60, 2, 1, 1, red, black);
61
      
62
    delay_ms(1000);
63
64
    LCD_Print(" Test2345", 20, 100, 2, 1, 1, red, black);
65
66
      }
67
      else
68
      {
69
        LCD_Print("I2C Error", 1, 60, 2, 1, 1, red, black);
70
      }
71
  
72
  }
73
}
74
75
//  Enhanced delay-routine (wait) as as the standard delay routine (_delay_ms) is not able to delay
76
//  more than 17 ms maximum as of the used 8-bit-timer (depending on used crystal)
77
void delay_ms(uint16_t period)   //delay routine (milliseconds)
78
{
79
  for(unsigned int i=0; i<=period; i++)
80
    _delay_ms(1);
81
}

von Daniel F. (mcnanuk)


Lesenswert?

Ich bin einen Schritt weiter. Ich hatte ja 6,3 kOhm Widerstände 
verwendet. Diese habe ich durch 4,7 k ersetzt.

Ich glaub es ja nicht, dass es daran gelegen hat, denn im Handbuch des 
Boards steht ganz deutlich 4,7 BIS 10 kOhm.... was bin ich froh das 
nicht als SMD Bauteile direkt aufs board gelötet zu haben....

2 Tage Fehlersuche, und um einige Erfahrung reicher...




Zur Berechnung.
Laut Datenblatt:
                       Min.    Typ.    Max
Zero pressure offset   03D7    0666    08F6
Full scale span (FSS)  63D6    6666    68F5

Meine Anzeige bei gemessenen 1004 mbar (habe noch ein kalibriertes 
Referenzgerät) ist nach meiner berechnung der Variablen int1:

6D5F oder eben 27999. (schankt zwischen 27991 und 28005)
Das ist aber eigentlich zu hoch, wenn ich obige Tabelle anschaue, oder?
Selbst wenn ich die ungenauigkeit von +-1% berücksichtige,  kommt es 
nicht hin. Der Sensor misst Drücke von 0 ... 1 bar. Dann wäre diese 
Abweichung fast 50 mbar.

>Wenn du dazu Fragen hast, gib die vollständige Bezeichnung deines
>Sensors an, damit man die Antworten am konkreten Modell festmachen kann.

SQ277 - 1FHU von Sensor Tronic

von Abdul K. (ehydra) Benutzerseite


Lesenswert?

Habe den Thread kurz überflogen. Also der Sensor müßte auch locker mit 
10K Pull-Ups funzen.

Geht er nun oder nicht?
Wenn nicht: Ist bei deinem Aufbau die Masse des Sensors mit der des 
Controllers verbunden? Muß so sein! Das kann man auf deinem Foto nicht 
recht erkennen. Soweit ich weiß, hast du doch eine Hilfsspannungsquelle 
dran??

Dann könntest du noch einen Bus-Scan machen - also alle Bus-Adressen in 
einer Schleife abklappern. Irgendwann meldet sich der Slave mit einem 
ACK.

Der Sensor scheint auch ein echter i2c-Slave zu sein. Da gibts nämlich 
welche, die sich als i2c bezeichnen und es dann nicht wirklich sind.

Ansonsten sich einfach stoisch an die NXP-Doku halten inkl. deren 
Timing!

Es kann auch dazu kommen, das der Slave in einem anderen Bus-State 
hängenbleibt als der Controller und sich dann nicht mehr meldet! Mit 
wegnehmen der VCC am Sensor probieren und dann später nach Bus-Reset 
googeln...

Viel mehr kann nicht schief gehen!

von Harald (Gast)


Lesenswert?

nix is absolut.

von Daniel F. (mcnanuk)


Lesenswert?

Ja es funktioniert jetzt, jedenfalls bekomme ich Werte. Der Sensor war 
von Anfang an mit der Masser des µC verbunden. Den Fehler hab ich an 
einer anderen Stelle mal gemacht, passiert nicht wieder :)

Jetzt ist nur eben das Problem mit den zu hohen Werten. Oder ist die 
Ausgabe richtig und ich übersehe nur etwas ?

>nix is absolut.
da hast du absolut Recht :D

von Daniel F. (mcnanuk)


Lesenswert?

Oh Herr lass Hirn ra...

Natürlich stimmt alles... Ich habe vergessen den Offset dazuzurechnen, 
und wenn ich das tue, und die 1,25% Messungenauigkeit berücksichtige, 
dann passt es ziemlich genau.

Jetzt also nur noch kalibrieren.

Danke für alle, die sich Gedanken gemacht haben, und speziell Stefan B.
Dank Leuten wie dir hab ich nicht schon längst alles hingeworfen, und 
lerne immer wieder dazu.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Daniel F. schrieb:

> Wenn die Slave Adersse falsch wäre, müsste dann die i2c_start-Methode
> nicht 0 als result geben ?

Nein. 0 ist laut Doku der Library der Erfolgsfall (warum auch immer).

Klasse, dass du jetzt den Sensor über I2C benutzen kannst! Ich freue 
mich mit dir. Und ein kleines Erfolgserlebnis habe ich selbst gerade: 
Mein DSL Router gab den Geist auf und jetzt habe ich endlich den Ersatz 
am rennen!

von Daniel F. (mcnanuk)


Lesenswert?

wie gewonnen so zerronnen....

Ohne Änderung geht es plötzlich wieder nicht, und zeigt I2C Error, da 
der start 1 zurück gibt.

Wenn ich könnte würd ih das Ding zertreten.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Daniel F. schrieb:

> Wenn ich könnte würd ih das Ding zertreten.

Kopp nicht hängen lassen! Schliesslich hat es mal funktioniert, d.h. 
nciht alles ist verloren. Das kriegen wir hin.

Derweil meine Lieblingshelden Geek und Poke:
http://geekandpoke.typepad.com/geekandpoke/2010/10/yiw.html

von Abdul K. (ehydra) Benutzerseite


Lesenswert?

Du hast die Geschichte mit möglichem falschen Busstate bei Master und 
Slave beachtet?
Du bist langsam genug?

von Daniel F. (mcnanuk)


Lesenswert?

Stefan B. schrieb:
> Derweil meine Lieblingshelden Geek und Poke:
> http://geekandpoke.typepad.com/geekandpoke/2010/10/yiw.html

Danke dafür :)

Es hat alles funktioniert, also habe ich meine restliche Hardware 
angeschlossen, einen Schlauch am Sensor befestigt, und es probiert. Es 
ging nicht, also alles wieder abgezogen bis auf den I2C und den Sensor.

Bei der Schlauchmontage ist sicher nix passiert, ich war sehr 
vorsichtig. Auch die Eingangsspannung von 4,7 V passt, und beide 
Ausgänge SCL und SDA sind auf High (4,62 V)

Ab und an messe ich am Eingang um die 3,7 V, und an den Ausgängen etwas 
über 4,8V macht für mich keinen Sinn, und es ist auch kein Muster zu 
beobachten wann dieser Fall auftriff.

Die Leitungen habe ich alle überprüft und alle Lötstellen gechecked. 
Alles so wie es sein soll.

Software alles so wie es war, Pins unberührt so gelassen wie es default 
ist, der Rest wie gehabt.
1
#include <stdlib.h>
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
#include <avr/pgmspace.h>
5
#include <util/delay.h>
6
#include <string.h>
7
#include "glcd-Display3000-211.h"
8
#include "i2cmaster.h"
9
10
11
#define SQ277  0xF0      // device address of SQ277, see datasheet
12
 
13
#define F_CPU 16000000UL
14
  
15
16
int main( void )
17
{
18
  unsigned char buffer[30];  
19
20
  
21
  LCD_Init();  // caution: this also defines SPI for the display and also PortB (all ports but MISO are output)   
22
  
23
  delay_ms(1000);
24
       LCD_Cls(black);  
25
 
26
    sei();
27
28
  Orientation = Portrait180;
29
  LCD_Cls(green);
30
      LCD_Print("       mbar", 20, 60, 2, 1, 1, yellow, black);
31
    
32
    uint8_t byte1;//= 0b00001111;
33
    uint8_t byte2;//= 0b00000011;
34
    int16_t int1;
35
    int16_t x=0;
36
    int16_t y=i2c_rep_start(SQ277+I2C_READ);
37
    
38
  
39
  LCD_Print(itoa( y,buffer,10), 1, 1, 2, 1, 1, yellow, black);
40
    // 2. Auslesen (innerhalb while(1))
41
    
42
      if ( y ==0 )
43
      {
44
    delay_ms(1000);
45
        byte1 = i2c_readAck();
46
47
        byte2 = i2c_readNak();
48
49
        i2c_stop(); // Einsparbar, macht i2c_readNak() mit
50
51
        // 3. Ausgeben
52
        int1 = ((int16_t) byte1 << 8) | byte2;
53
        LCD_Print(itoa(int1,buffer,16), 1, 60, 2, 1, 1, yellow, black);
54
        LCD_Print(itoa(int1,buffer,10), 1, 80, 2, 1, 1, yellow, black);
55
      
56
    delay_ms(1000);
57
58
    LCD_Print(" Es geht", 20, 100, 2, 1, 1, red, black);
59
60
      }
61
      else
62
      {
63
        LCD_Print("I2C Error", 1, 80, 2, 1, 1, red, black);
64
      }
65
66
67
  while(1){
68
LCD_Print(itoa( x++,buffer,10), 1, 120, 2, 1, 1, yellow, black);
69
  }
70
}
71
72
//  Enhanced delay-routine (wait) as as the standard delay routine (_delay_ms) is not able to delay
73
//  more than 17 ms maximum as of the used 8-bit-timer (depending on used crystal)
74
void delay_ms(uint16_t period)   //delay routine (milliseconds)
75
{
76
  for(unsigned int i=0; i<=period; i++)
77
    _delay_ms(1);
78
}

von Daniel F. (mcnanuk)


Lesenswert?

Abdul K. schrieb:
> Du hast die Geschichte mit möglichem falschen Busstate bei Master und
> Slave beachtet?
> Du bist langsam genug?

Was meinst du damit ? Wahrscheinlich hab ich das nicht beachtet. Ich 
habe in dem File von Fleury meine Taktrate eingetragen und verwende die 
Methoden unverändert.

Das Datenblatt sagt

SCL clock frequency F SCL --- 400 kHz
also hab ich hier
>#define SCL_CLOCK  400000L

eingetragen. Damit ist TWBR =12.

von Abdul K. (ehydra) Benutzerseite


Lesenswert?

Laß mich raten Daniel, du bist noch sehr jung? Glaubst an das gute in 
der Technik??
Nimm mal 1-10KHz zum Testen. Wozu 400KHz? 400KHz können sehr viele 
i2c-Chips gar nicht. Falls es dieser kann, dann vielleicht der nächste 
am Bus nicht und dann haste das längst vergessen was du vor 2-3 Jahren 
gemacht hast und suchst in der nächsten Projekterweiterung schlicht 
Gespenster...

Aber jeder lernt dazu.

Gehe mal von mir aus, OK der Kram will nicht! Frage: Warum nicht. Liegts 
an der unterschiedlichen Stromversorgung? Also Datenblatt nach maximum 
ratings untersuchen...
Oh! Keine angegeben! Wo ist der Spannungsbereich für VCC? Wo der 
maximale Kurzschlußstrom für SCL und SDA? Und die wichtigste Frage: Darf 
man die beiden Busleitungen mit Spannungen betreiben, die oberhalb von 
VCC sind??
Ah, altes Dateblatt von 1997. Gibts den Chip dann aktuell zu kaufen? 
Suchen wir mal nach dem aktuellen Datenblatt, vielleicht steht da mehr 
drin. Könnte eine typische ASIC-Geschichte sein: Chip wird zugeliefert 
zum Sensorhersteller. Der hat wiederum zwar von Mechanik und MEMS oder 
so plan, aber nich vom ASIC. Folge: Datenblatt wird meist Mist.

So, das sende ich erstmal ab falls Stromausfall...

von Stefan B. (stefan) Benutzerseite


Lesenswert?

> Software alles so wie es war, Pins unberührt so gelassen wie es default
> ist, der Rest wie gehabt.

Eigentlich nicht.

Der Quellcode in
Beitrag "Re: I2C Kommunikation zwischen Atmega128 und Drucksensor"
ist eine deutliche Verschlimmbesserung. Da sind Bugs drin, die wir 
längst behoben hatten (F_CPU, while, ...). Aber ich muss jetzt in die 
Kiste morgen mehr.

von Abdul K. (ehydra) Benutzerseite


Lesenswert?

Ja, nun wieder da und sofort gibts eines auf die Öme!

Du hast offensichtlich nicht das hier gelesen:
http://www.sensortechnics.com/download/AN_I2C-Bus-HDI-HCLA-HCA-SSI_E_11155.pdf

Ferner gibts hier jemanden ders bestimmt zum Laufen brachte:
Beitrag "Neues Bauteil in Eagle zeichnen"

Sorry, dein Datenblatt ist von 2007.

Hm. Datenblatt kann ich dort nicht finden. Ähnlich wäre:
http://www.sensortechnics.com/download/DS_Standard-HDI_E_11650.pdf

Also nochmals die Frage: Kann man das Ding überhaupt noch kaufen, bzw. 
wurde es umbenannt?

Dann habe ich maximum rating immerhin für 5V-Betrieb auf der ersten 
Seite. OK, das paßt.

Weiter schreiben sie, warum auch immer, der Sensor soll mit mindestens 
100KHz betrieben werden. Ist nicht nach i2c-Spec von NXP. Aber dann 
stells eben auf 100KHz ein.

von Daniel F. (mcnanuk)


Lesenswert?

Nenn mich blauäugig, aber ich dachte, egal wie alt eine Software ist, 
das Datenblatt dazu stimmt.
Ich weiss nicht, ob man den Sensor noch kaufen kann, und wie er bezogen 
worden ist. Wohl direkt von ST.

Ich habe die Hardware nur in die Hand bekommen.

Auf Seite 9 des ersten Dokuments steht einiges was hinhauen könnte:

Both SCL and SDA lines have to be connected
to a 5 V supply voltage via pull-up resistors RP
as shown in Fig. 12. Sensortechnics
recommends to use 1.5 kΩ resistors.
Additionally, serial resistors RS of max. 240 Ω
should be used in each communication line.

Tja wieder bin ich überfragt. In dem Handbuch meines Boards steht nunmal 
4,7k bis 1k Ohm. Und jetzt steht hier 1,5 kOhm.

Wie schon geschrieben hat es mit 4,7 auch den ganzen Tag funktioniert. 
Und egal ob ich 400KHz oder 100kHz als SCL Takt angebe, es tut sich nix.


Naja heute ist mal Schluss... Danke für deine Mühen Abdul. Wenn nichts 
hilft, baue ich am Montag die neue Schaltung. vielleicht klappt es ja 
und es lag daran. Aber dazu muss ich erst mal wieder einkaufen gehen...

von Abdul K. (ehydra) Benutzerseite


Lesenswert?

Wenn du die Schaltung in die Hand bekamst, besteht natürlich immer die 
Möglichkeit einer Vorschädigung.

Nimm die genauen Widerstandswerte nicht so ernst. Das ist bei i2c völlig 
unkritisch! In deiner Schaltung wird alles zwischen 330 Ohm und 100K als 
Pull-Up problemlos laufen.
Du schriebst von 5cm Abstand. Dann brauchste auch die Längswiderstände 
nicht. Die benutzt man, wenn der i2c über Modulgrenzen hinaus betrieben 
wird. Grundig hat früher in deren Fernsehern an jedem Modul 100 Ohm in 
Reihe gehabt. Unterdrückt das Verschleppen von HF-Störungen.


Aus meiner fernen Sicht würde ich auf deine Software tippen. Habe zwar 
schon selbst Bit-banging am i2c betrieben, ist mir aber ehrlich zu viel 
Aufwand in deine Source jetzt tiefer einzusteigen. Zumal die 
eigentlichen Ansteuerroutinen offensichtlich nicht dabei sind und ich 
deinen Controller noch nie benutzt habe.

Alternative wäre auch noch, erstmal einen anderen Chip z.B. EEPROM 
anzusteuern. Schon wegen des Erfolgserlebnisses!

Viel Glück!

von Abdul K. (ehydra) Benutzerseite


Lesenswert?

Du hast kein Scope?

von Daniel F. (mcnanuk)


Lesenswert?

leider nein... nicht hier.
Und da wo ich eines habe, kann ich nicht programmieren, da mein Laptop 
versagt hat :)

Ich werde mich morgen um die Software nochmal kümmern... kann ja nicht 
angehen sowas... ;) ich danke dir jedenfalls auch für die Erklärung des 
anderen Schaltplans...

Vorschädigung ist nicht. Der Sensor war verpackt, schaltung hab ich 
selbst gelötet. Sensor ist fabrikneu... naja jedenfalls ungebraucht, 
übers baujahr schweigen wir jetzt einfach mal :)

von Daniel F. (mcnanuk)


Lesenswert?

Stefan B. schrieb:
> Da sind Bugs drin, die wir
> längst behoben hatten (F_CPU, while, ...)

OH Mann bin ich ein IDIOT, ich sollte es echt lassen so spät noch dran 
zu sitzen.

Ich hab doch tatsächlich die i2c_init() gelöscht. klar dass das nix 
wird. Verdammt.

Jetzt gehts wieder, mal sehen wie lang.

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.