Go Down

Topic: Probleme mit I2C (Read 232 times) previous topic - next topic

El_Duino

Oct 12, 2017, 11:38 am Last Edit: Oct 12, 2017, 12:00 pm by El_Duino
Hey Leute,

ich benötige etwas Hilfe bei meinem Arduino Programm.

Kurze Zusammenfassung: ich soll von meinem Ausbilder aus ein "einfaches" I2C-Programm erstellen damit es nachfolgende Azubis einfacher haben in das Thema I2C einzusteigen.

Ich habe mir das Buch "Die elektronische Welt mit Arduino entdecken" von Erik Bartmann zur Hilfe genommen und daraus das Programm abgeschrieben, welches einen EEPROM ansteuert.
Jedoch entsteht ein Fehler beim Überprüfen und ich verstehe einige Programmzeilen nicht.

Code: [Select]

                                 /*Ansteuerung eines EERPOM per I2C*/


#include <Wire.h>                                                    
#define I2Cadresse 0x50                                             //Adresse des Speicherbausteins festlegen

void setup()
{
 Wire.begin();                                                       //Starten des I2C-bus
 Serial.begin(9600);                                                 //stellt die Serielleschnittstelle zur Verfügung; Übertragungsrate: 9,6 kbit/s
 unsigned int speicheradresse = 0;                                   //Startadresse
 byte wert = 7;                                                      //Zu speichernder Wert
 schreibeEEPROM(I2Cadresse, speicheradresse, wert);                  //schreiben des vorgegebenen Werts
 Serial.println(leseEEPROM(I2Cadresse, speicheradresse), HEX);       //lesen des EEPROM´s
}

void loop()
{
 void schreibeEEPROM(int I2Cadresse, unsigned int speicheradresse, byte daten)
 {
   Wire.beginTransmission(I2Cadresse);                               //Verbindung zu I2C einleiten
   Wire.write((byte)(speicheradresse >> 8 ));                        //höchstwertiges Byte (MSB) senden
   Wire.write((byte)(speicheradresse & 0xFF));                       //niederwertiges Byte (LSB) senden
   Wire.write(daten);                                                //Daten-Byte senden
   Wire.endTransmission();                                            //Verbindung zu I2C trennen
   delay(5);                                                          //5ms Pause
 }
byte leseEEPROM(int I2Cadresse, unsigned int speicheradresse)
 {
   byte datenByte = 0xFF;
   Wire.beginTransmission(I2Cadresse);                                 //I2C Verbindung starten    
   Wire.write((byte)(speicheradresse >>8));                             //höchstwertiges Byte (MSB) senden
   Wire.write((byte)(speicheradresse & 0xFF);                          //niederwertiges Byte (LSB) senden
   Wire.endTransmission();                                             //Verbindung zu I2C trennen
   Wire.requestFrom(I2Cadresse, 1);                                    //Anfordern der Daten vom Slave; "1" steht für eon Daten-Byte
   if(Wire.available()) datenByte 0 Wire.read();                       //sind Daten vorhanden?
   return datenByte;                                                   //Daten-Byte zurückliefern    
 }
}


Die Arduino IDE zeigt mir einen Fehler in der Zeile

schreibeEEPROM(I2Cadresse, speicheradresse, wert);                  //schreiben des vorgegebenen Werts

im void setup() und zwar soll diese nicht deklariert sein aber das wird sie doch im void loop?!
Zudem verstehe ich diese Programmzeile nicht wirklich und finde auch keine Erklärung dazu im Internet.

combie

2 lokale Funktionen in Loop?
Das willst du nicht!
"Freiheit, Gleichheit, Brüderlichkeit!"
Aber wie gelangen wir zu den Tätigkeitswörtern?
Quelle: Stanislaw Jerzy Lec

MicroBahner

#2
Oct 12, 2017, 11:55 am Last Edit: Oct 12, 2017, 11:57 am by MicroBahner
Bitte setze deinen Code in Code-Tags ( links oben ). Dann wird er besser lesbar dargestellt, und es entstehen auch keine emoticons wo sie nicht hingehören.

Ich kann mir nicht vorstellen, dass das so in dem Buch steht. Du defninierst die Funktionen 'schreibeEEPROM' und 'leseEEPROM' innerhalb einer anderen Funktion.  loop() ist ja ebenfalls eine Funktion. Das funktioniert aber nicht, da sie so nicht global bekannt sind. Du musst diese Funktionen ausserhalb von loop definieren. Dann ist dein loop() zwar leer, aber Du willst ja scheinbar im setup nur mit einmal schreiben und lesen testen, ob der Zugriff auf das EEPROM funktioniert.
Gruß, Franz-Peter

Theseus

Hey Leute,

ich benötige etwas Hilfe bei meinem Arduino Programm.

Kurze Zusammenfassung: ich soll von meinem Ausbilder aus ein "einfaches" I2C-Programm erstellen damit es nachfolgende Azubis einfacher haben in das Thema I2C einzusteigen.
Nur als Idee: In Bezug auf I2C hat es bei mir bei diesem Beispiel zur Nutzung der DS3231-RTC klick gemacht: http://tronixstuff.com/2014/12/01/tutorial-using-ds1307-and-ds3231-real-time-clock-modules-with-arduino/
Mit dem Datenblatt kann man dann weitere Funktionen wie das Auslesen der Temperatur hinzufügen. Für mich wirkte die Benutzung der RTC sehr motivierend.

El_Duino

#4
Oct 12, 2017, 12:08 pm Last Edit: Oct 12, 2017, 12:18 pm by El_Duino
Vielen Dank für die schnelle Antwort. Habe das mit dem code geändert (war mein erster Post, bin noch nicht so drin in dem Thema  aber vielen Dank )
Ich habe den Fehler gefunden, denn um buch steht:

Code: [Select]


void loop(){ /* leer */}



Hätte ich selbst drauf kommen müssen, vor allem weil er es vorher noch extra erwähnt hatte das man bloß nicht mit dem loop arbeiten soll da der EEPROM nur gewissen lese/schreib Zyklen hat.

Dennoch habe ich den Fehler: 'schreibeEEPROM' was not declared in this scope

MicroBahner

#5
Oct 12, 2017, 12:15 pm Last Edit: Oct 12, 2017, 12:24 pm by MicroBahner
Super,
für den Test ist sicher richtig, das nicht im loop() zu machen, aber in einem echten Anwendungsprogramm wird es dann schon im loop() verwendet werden (nicht die Definition, aber der Funktionsaufruf ). Dann muss man aber auf andere Weise sicherstellen, dass das EEPROM nicht in jedem loop() Durchlauf, sondern nur bei Bedarf geschrieben wird, denn sonst ist es in der Tat schnell hinüber.
Lesen ist übrigens kein Problem, nur zu oft Schreiben macht das EEPROM kaputt. Die halten zwar normalerweise >100000 Schreibzyklen aus, aber wenn man das in jedem loop macht, schafft der Arduino das ziemlich flott ;)
Gruß, Franz-Peter

uwefed

Wir reden von externen EEPROMs und nicht vom EEPROM im ATmega. Die externen halten normalerweise 1 000 000 Schreibzyklen aus.
Grüße Uwe

combie

Quote
Dennoch habe ich den Fehler: 'schreibeEEPROM' was not declared in this scope
Der Fehler ist doch klar!

Und die Lösung steht schon drin!
Deklariere : 'schreibeEEPROM'
Und dann bitte so, dass sie auch im Sichtbarkeitsbereich liegt.
"Freiheit, Gleichheit, Brüderlichkeit!"
Aber wie gelangen wir zu den Tätigkeitswörtern?
Quelle: Stanislaw Jerzy Lec

MicroBahner

Upps, ja die Nullen .. da fehlte eine  :-[ . Aber auch das schafft der Arduino in sehr überschaubarer Zeit, wenn man in jedem loop() schreibt.
Gruß, Franz-Peter

MicroBahner

Deklariere : 'schreibeEEPROM'
In der Arduino IDE sollte die Definition der Funktion eigentlich ausreichen. Die Frage ist, wie sein Sketch jetzt aussieht.
Gruß, Franz-Peter

Tommy56

Dennoch habe ich den Fehler: 'schreibeEEPROM' was not declared in this scope
Die Antwort hast Du doch schon in #1 bekommen.

Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

El_Duino

#11
Oct 12, 2017, 01:21 pm Last Edit: Oct 12, 2017, 01:39 pm by El_Duino
so sieht aktuell mein Programm aus:
Code: [Select]

                                   /*Ansteuerung eines EERPOM per I2C*/


#include <Wire.h>                                                     
#define I2Cadresse 0x50                                               //Adresse des Speicherbausteins festlegen

void setup()
{
  Wire.begin();                                                       //Starten des I2C-bus
  Serial.begin(9600);                                                 //stellt die Serielleschnittstelle zur Verfügung; Übertragungsrate: 9,6 kbit/s
  unsigned int speicheradresse = 0;                                   //Startadresse
  byte wert = 7;                                                      //Zu speichernder Wert
  schreibeEEPROM(I2Cadresse, speicheradresse, wert);                  //schreiben des vorgegebenen Werts
  Serial.println(leseEEPROM(I2Cadresse, speicheradresse), HEX);       //lesen des EEPROM´s
}

 void loop()
{
 /* leer */
}

 void schreibeEEPROM(int I2Cadresse, unsigned int speicheradresse, byte daten)
 {
   Wire.beginTransmission(I2Cadresse);                               //Verbindung zu I2C einleiten
   Wire.write((byte)(speicheradresse >> 8 ));                        //höchstwertiges Byte (MSB) senden
   Wire.write((byte)(speicheradresse & 0xFF));                       //niederwertiges Byte (LSB) senden
   Wire.write(daten);                                                //Daten-Byte senden
   Wire.endTransmission();                                            //Verbindung zu I2C trennen
   delay(5);                                                          //5ms Pause
 }
 byte leseEEPROM(int I2Cadresse, unsigned int speicheradresse)
 {
   byte datenByte = 0xFF;
   Wire.beginTransmission(I2Cadresse);                                 //I2C Verbindung starten   
   Wire.write((byte)(speicheradresse >>8));                             //höchstwertiges Byte (MSB) senden
   Wire.write((byte)(speicheradresse & 0xFF);                          //niederwertiges Byte (LSB) senden
   Wire.endTransmission();                                             //Verbindung zu I2C trennen
   Wire.requestFrom(I2Cadresse, 1);                                    //Anfordern der Daten vom Slave; "1" steht für eon Daten-Byte
   if(Wire.available()) datenByte 0 Wire.read();                       //sind Daten vorhanden?
   return datenByte;                                                   //Daten-Byte zurückliefern   
 }


@combie das habe ich schon verstanden aber wie soll ich das deklarieren ?

Bitte habt etwas Verständnis dafür dass die Arduino Umgebung noch relativ Neuland für mich ist.

MicroBahner

#12
Oct 12, 2017, 01:39 pm Last Edit: Oct 12, 2017, 01:55 pm by MicroBahner
Der Fehler liegt etwas tiefer. Die Fehlermeldung ist eine Folge davon, dass in der Definition der Funktion ein Fehler aufgetreten ist. Das Problem ist deine Namensgebung.
Hier:
Code: [Select]
#define I2Cadresse 0x50                                               //Adresse des Speicherbausteins festlegen
definiertst Du I2Cadresse als Konstante für den Precompiler. D.h. überall wo 'I2Cadresse' in deinem Sketch vorkommt, setzt der Precompiler '0x50' ein, und erst dann wird kompiliert.

In deinen Definitionen benutzt den gleichen Namen für die Funktionsparameter:

Code: [Select]
void schreibeEEPROM(int I2Cadresse, unsigned int speicheradresse, byte daten)
und
Code: [Select]
byte leseEEPROM(int I2Cadresse, unsigned int speicheradresse)
Hier ersetzt der Precompiler das nun auch durch '0x50', was dann aber beim Kompilieren zum Fehler führt, denn in der Definition der Funktion kannst Du keinen Zahlenwert als Parameternamen verwenden.

Du musst in der Definition deiner beiden Funktionen einen anderen Namen verwenden.
Hier zeigen sich die Tücken des Precompilers, der nur stur Textersetzungen macht, ohne die Namensräume zu kennen.
Mit
Code: [Select]
const byte I2Cadresse = 0x50;                                               //Adresse des Speicherbausteins festlegen
hättest Du das Problem nicht bekommen.
Der Code enthält aber dann noch weitere Fehler.

Edit: Es ist deshalb auch eine sehr sinnvolle Übereinkunft, #define - Konstanten immer rein in Großbuchstaben zu benennen, damit es keine Überschneidungen mit Variablennamen gibt.
Gruß, Franz-Peter

El_Duino

Danke dafür, habe noch ein paar Fehler gefunden bzw. finden lassen;)

Go Up