RTC DS1307 & LCD 12864B mit SPT Modul (? ST7920)

Hallo erstmal im Deutschsprachigen Teil, Super das es sowas gibt.

Ich habe da ein kleines Problem mit meiner RTC Uhr und meinem neu erworbenen Display. Ich kann sie zwar einzeln nutzen, aber leider irgendwie nicht zusammen.

Die RTC habe ich wie folgt an meinen Mega angeschlossen.
SQ -
DS -
SCL - Pin21
SDA - Pin20
VCC - +5V
GND - GND
Diese benötigt wohl die Wire.h.

#include "Wire.h"
#define DS1307_ADDRESS 0x68

Das LCD Modul habe ich über das SPT Modul Angeschlossen, und dort auch den kleinen switch von Paralel auf SPI umgestellt.
Nutze hierfür die U8GLib.

U8GLIB_ST7920_128X64 u8g(30, 32, 31, U8G_PIN_NONE );// SPI Com: SCK = en = 30, MOSI = rw = 32, CS = di = 31

SCK -> Pin30
CS -> Pin31
SID -> Pin32
VCC -> +5V
GND -> GND

Nun muss ich zugeben, das ich mittlerweile auch immer mehr mit den Kürzeln durcheinander komme, und vermute das beide Module irgendwie Kollidieren.
Ich dachte das die RTC ein I2C und das Display mit SPI Seriell angesprochen wird(Mich wundert dabei das ich keinen Hardware Port belegen muss, sondern die Pins frei Definieren kann Ohne Soft Serial zu verwenden.). Oder sind beides I2C Module, so das ich beide Module miteinander verbinden muss?

Also:
RTC_SCK - LCD_SCK -> Pin21
RTC_SDA - LCD_SID?? -> Pin20??
Wohin dann mit dem LCD_CS sowohl auch der RTC_DS der ja nirgends angeschlossen ist?
Warum kann ich die Pins für den I2C Bus nicht frei wählen, sondern müssen auf dem Pin20-SDA & Pin21-SCL beim Mega und 4/5 beim Uno sein?

Also wenn mir da jemand auf die Sprünge helfen könnte fände ich sehr nett.

Lieben Dank,
Gerrit

SPI ist Hardware implementiert. Darum kannst Du nicht x-beliebige Pins nehmen.
Beim Mega sind das: SPI: 50 (MISO), 51 (MOSI), 52 (SCK), 53 (SS). Wobei Das SS-Pin (oder CS genannt) frei wählbar ist, weil jeder Baustein am SPI einen eigenen SS braucht.
Jetzt weiß ich nicht ob die U8GLIB Bibiothek nicht die HW SPI- Schnittstelle benutzt sondern in SW emuliert.
Welche Bibliothek benutzt Du?
Grüße Uwe

Okay soweit Ordnet sich das ein wenig bei mir.

Ich nehme mal an das das LCD-SPI dann wohl über die U8GLIB per Software Emuliert wird, denn wenn ich die Pins umkonfiguriere z.b.

U8GLIB_ST7920_128X64 u8g(30, 32, 31, U8G_PIN_NONE );// SPI Com: SCK = en = 30, MOSI = rw = 32, CS = di = 31

läuft das Display auch an diesen Pins.

Dann nehme ich auch mal an das I2C ebenso per Hardware fest liegt (Mega 20/21) & (Uno 4/5), denn wo anders läuft die RTC nicht, und lässt sich auch nicht stellen oder auslesen. würde dann auch erklären warum ich nirgends bei der <Wire.h> einen Pin definieren kann, sondern nur eine Adresse und auch keinen CS oder SS Pin am RTC Modul habe. Richtig?

Nun habe ich das LCD mal an folgende pins gehängt.

U8GLIB_ST7920_128X64 u8g(52, 51, 53, U8G_PIN_NONE );// SPI Com: SCK = en = 52, MOSI = rw = 51, CS = di = 53

MISO brauche ich wohl beim LCD eher weniger weil ich ja nur Daten an das Display sende, und den Pin hätte ich nun auch gar nicht auf dem LCD Modul.
Ja das LCD funktioniert auch an Pin 52,51,53.. :slight_smile:

Also sind I2C und SPI eigendlich komplett voneinander getrennte Wege? Dann müsste ich doch villeicht den Fehler eher in der Software suchen?
Ich dachte wenn das Display im einen Sketch funktioniert, aber die RTC nicht | Im anderen die RTC aber das Display nicht, das ich da villeicht was falsch verkabelt habe.

Sonst weis ich momentan auch nicht so ganz weiter...
Vielleicht Schlaf ich nochmal ne Nacht drüber.

Hallo

U8glib unterstützt sowohl HW SPI als auch SW SPI (ohne zusätliche libs).

U8GLIB_ST7920_128X64 u8g(30, 32, 31, U8G_PIN_NONE );// SW SPI, alle Pins frei wählbar
U8GLIB_ST7920_128X64 u8g(31, U8G_PIN_NONE );// HW SPI, SCK und MOSI müssen entsprechend an die Ausgänge des SPI subsystem angeschlossen werden

Siehe auch: Google Code Archive - Long-term storage for Google Code Project Hosting.. Dort sind die Konstruktoraufrufe erklärt.

Ja das LCD funktioniert auch an Pin 52,51,53..

So soll es auch sein.

Also sind I2C und SPI eigendlich komplett voneinander getrennte Wege?

Sehe ich auch so.
Wenn sich RTC und das Display keine Pins teilen, sehe ich keinen Grund warum das nicht gemeinsam funktionieren sollte.

Grüße,
Oliver

Beim Arduino UNO liegt I2C an A4 und A5 nicht an 4 und 5.
Versuch mal mit dem Arduino Playground - I2cScanner ob dort die RTC gesehen wird.

Fürs WeitergeholfenWerdenWollen bitte Sketch der nicht funktioniert und genaue Fehlerbeschreibung.

Grüße Uwe

Nun habe ich heute mal alle Kabel getauscht, und das Breadboard entfernt, um auch diese Fehlerquellen ausschließen zu können.
Dann habe mal den Scanner ausprobiert, und der zeigt mir auch 2 Devices an..
0x68 für die RTC
0x50 ... Ich glaube das ist der Speicher auf der RTC. Irgendwas hatte ich mal gelesen das man da ein paar Bytes Speichern kann?
Leider zeigt die Uhr Nicht wirklich was an. Die 165/165/165 45:165:165 bekomme ich auch wenn die RTC gar nicht am Board dran hängt.
Ich würde also meinen das die gar nicht gefunden wird.

Da ich im Fritzing das LCD mit dem SPI Anschluss sowie die RTC irgendwie nicht gefunden habe habe ich mal ein paar Bilder gemacht.

www.corsmeyer.de/user/arduino/RTCProblem.jpg

Brauche ich vielleicht 4,7K Pullups? Ich dachte die bräuchte man nur beim 1-Wire?

// LCD
#include "U8glib.h"
U8GLIB_ST7920_128X64 u8g(52, 51, 53, U8G_PIN_NONE );// SPI Com: SCK = en = 30, MOSI = rw = 32, CS = di = 31

int count = 0;

//RTCModule
#include "Wire.h"
#define DS1307_ADDRESS 0x68
byte zero = 0x00; //workaround for issue #527


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

// *******  Hatte ich Vergessen!
        Wire.begin();
}

void loop(void) {
  u8g.firstPage();  
  do {
    draw();
    Serial.println(printDate());
  } while( u8g.nextPage() );
  delay(5);
}

void draw(void) {

  u8g.setFont(u8g_font_4x6);
  u8g.setPrintPos(0, 6); 
  int LineNumber = 0;

  LineNumber++;u8g.setPrintPos(0, 6*LineNumber);  u8g.print("Temperatur View   ");  
  LineNumber++;
  LineNumber++;u8g.setPrintPos(0, 6*LineNumber);  u8g.print("Vorlauf   =+32 C |"); 
  LineNumber++;u8g.setPrintPos(0, 6*LineNumber);  u8g.print("Ruecklauf =+27 C |");  
  LineNumber++;u8g.setPrintPos(0, 6*LineNumber);  u8g.print("Aussen    =- 3 C |");  
  LineNumber++;u8g.setPrintPos(0, 6*LineNumber);  u8g.print("Solar     =+14 C |");  
  LineNumber++;u8g.setPrintPos(0, 6*LineNumber);  u8g.print("W.Wasser  =+40 C |");  
  LineNumber++;u8g.setPrintPos(0, 6*LineNumber);  u8g.print("Licht     =" + (String)analogRead(7));
  LineNumber++;u8g.setPrintPos(0, 6*LineNumber);  u8g.print(printDate());
  LineNumber++;u8g.setPrintPos(0, 6*LineNumber);  u8g.print(count);
  count++;
}

String printDate(){
    // Reset the register pointer
  Wire.beginTransmission(DS1307_ADDRESS);
  Wire.write(zero);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_ADDRESS, 7);

  int second = bcdToDec(Wire.read());
  int minute = bcdToDec(Wire.read());
  int hour = bcdToDec(Wire.read() & 0b111111); //24 hour time
  int weekDay = bcdToDec(Wire.read()); //0-6 -> sunday - Saturday
  int monthDay = bcdToDec(Wire.read());
  int month = bcdToDec(Wire.read());
  int year = bcdToDec(Wire.read());

  
			String DTString =(String)LeadZero(monthDay) + "/" + 
					(String)LeadZero(month) + "/" + 
					(String)LeadZero(year) + " " + 
					(String)LeadZero(hour) + ":" + 
					(String)LeadZero(minute) + ":" + 
					(String)LeadZero(second);
		  return DTString;
}

byte decToBcd(byte val){
// Convert normal decimal numbers to binary coded decimal
  return ( (val/10*16) + (val%10) );
}

byte bcdToDec(byte val)  {
// Convert binary coded decimal to normal decimal numbers
  return ( (val/16*10) + (val%16) );
}

void setDateTime( byte monthDay,byte month,byte year , byte hour,byte minute, byte second, byte weekDay){

  Wire.beginTransmission(DS1307_ADDRESS);
  Wire.write(zero); //stop Oscillator

  Wire.write(decToBcd(second));
  Wire.write(decToBcd(minute));
  Wire.write(decToBcd(hour));
  Wire.write(decToBcd(weekDay));
  Wire.write(decToBcd(monthDay));
  Wire.write(decToBcd(month));
  Wire.write(decToBcd(year));
  Wire.write(zero); //start 
  Wire.endTransmission();
}

void setDateTime(){
  byte second =      00; //0-59
  byte minute =      17; //0-59
  byte hour =        23; //0-23
  byte weekDay =     2; //1-7
  byte monthDay =    01; //1-31
  byte month =       01; //1-12
  byte year  =       13; //0-99
  Wire.beginTransmission(DS1307_ADDRESS);
  Wire.write(zero); //stop Oscillator
  Wire.write(decToBcd(second));
  Wire.write(decToBcd(minute));
  Wire.write(decToBcd(hour));
  Wire.write(decToBcd(weekDay));
  Wire.write(decToBcd(monthDay));
  Wire.write(decToBcd(month));
  Wire.write(decToBcd(year));
  Wire.write(zero); //start 
  Wire.endTransmission();
}

String LeadZero(int Number){
	String ReturnNumber = (String)Number;
	if (Number <= 9){
		ReturnNumber = "0" + (String)Number;
	} 
	//Serial.println(ReturnNumber);
	return ReturnNumber;
}

... so an dieser Stelle brech ich mal ab...
Ich Dummdussel habe das Wire.begin() im Setup vergessen. (Ich schweige und versinke im Boden..)

Ich poste das Bild und den Code trotzdem, vielleicht Interessierts ja noch andere.

Vielen, vielen Dank für den Beistand, und gelernt habe ich trotzdem viel dabei..

Grüsse,
Gerrit

Hi

In der Tat brauchen die beiden I2C jeweils einen Pull-Up-Widerstand (üblicherweise 10K). Manchmal sind die aber auch schon verbaut.

Nettes Bild übrigens.

Grüße,
Oliver

Die DS1307 hat nur eine Adresse für die Register der RTC und die RAM-Speicherzellen. Lies Dir mal das Datenblatt durch.
Die RTC muß mit einer Zeit initialisiert werden ansonsten liest Du Hausnummern und die Zeit startet auch nicht.
Grüße Uwe