EA DOG 162 LCD und SPI

Hallo,

für das LCD gibt es ja die Library. Google Code Archive - Long-term storage for Google Code Project Hosting.

Wird in dem Code mit den Pins die Hardware SPI Schnittstelle verwendet?

LCD SI pin to digital pin 2
LCD CLK pin to digital pin 3
LCD RS pin to digital pin 4
LCD CSB pin to digital pin 5

Wird in dem Code mit den Pins die Hardware SPI Schnittstelle verwendet?

Nein, die Hardware SPI-Schnittstelle ist bei keinem mir bekannten Arduino auf diesen Pins zu finden.

Die Bibliothek verwendet die Hardware-Schnittstelle auch nicht, sie macht nicht einmal Direct-Port-Access, somit ist sie sehr langsam, was bei einem LCD aber nicht so relevant sein dürfte. Der grosse Vorteil: sie ist sehr portabel, dürfte also auch auf Arduino-Abkömmlingen (wie z.B. dem Intel Galileo) funktionieren.

Hallo,

gibt es eine Library für LCD die die Hardware SPI Schnittstelle nutzt?
Ich habe schon das WIFI-Shield im Einsatz mit SDcard welches SPI nutzt. Es wäre aus meiner Sicht Unsinn nochmal neue Pins zu verschwenden.

Mir ist für dieses LCD-Modul keine solche Bibliothek bekannt, aber es dürfte relativ einfach sein, die bestehende Bibliothek auf die Hardware-SPI-Schittstelle umzuschreiben.

Dazu musst Du nur die Initialisierung etwas anpassen und in writeChar und writeCommand der spiTransfer()-Aufruf durch diesen Code ersetzen:

digitalWrite(lcdCSB,LOW);
SPI.transfer(<value|cmd>);
digitalWrite(lcdCSB,HIGH);

wobei natürlich “<value|cmd>” entweder value oder cmd sein sollte. Eventuell musst Du noch das delayMicroseconds() anhängen, falls das Display dies wirklich benötigt.
Du sparst aber nur zwei Pins ein (MOSI, SCLK), die anderen werden weiterhin benötigt.

Hallo,

hast schon recht das man nur 2 von 4 Pins spart. Vielleicht probiere das dennoch mal anzupassen. Mit den Librarys hab ich noch nicht so drauf.

Danke für den Hinweis.

Hallo,

hab mir das mal angeschaut.

Original:

void DogLcd::writeChar(int value) {
    digitalWrite(lcdRS,HIGH); 		
    spiTransfer(value,30);
}

void DogLcd::writeCommand(int value,int executionTime) {
    digitalWrite(lcdRS,LOW);  			
    spiTransfer(value,executionTime);
}

wenn ich Dich richtig verstanden habe, müßte das dann so aussehen?

void DogLcd::writeChar(int value) {
    digitalWrite(lcdRS,HIGH); 			// High an RS ist Data Modus
    digitalWrite(lcdCSB,LOW);
    SPI.transfer(value);
    digitalWrite(lcdCSB,HIGH);
}

void DogLcd::writeCommand(int cmd, int executionTime) {
    digitalWrite(lcdRS,LOW);  			// Low an RS ist Command Modus
    digitalWrite(lcdCSB,LOW);
    SPI.transfer(cmd);
    digitalWrite(lcdCSB,HIGH);
}

und nach SPI.transfer ggf. noch ein delay einfügen um die geforderten Timings einzuhalten?
Mit welchen Takt arbeitet die Hardware SPI Schnittstelle. Immer default 4MHz?

wenn ich Dich richtig verstanden habe, müßte das dann so aussehen?

Ja, genau so. Allenfalls die erwähnte Verzögerung, aber die ist nicht sicher nötig.

Mit welchen Takt arbeitet die Hardware SPI Schnittstelle. Immer default 4MHz?

Ja, 4MHz ist der Default, Du kannst das über setClockDivider() auch selbst einstellen, falls Deine Hardware andere Anforderungen hat.

Hallo,

ich möchte das jetzt gleich richtig ändern. Habe dafür den/die Namen der Library geändert auf DogLcdSPI.

Ich erhalte jedoch beim kompilieren mehrere Fehlermeldungen:

C:\Portable Apps\Arduino IDE\libraries\DogLcdSPI\DogLcdSPI.cpp: In member function 'void DogLcdSPI::writeChar(int)':
C:\Portable Apps\Arduino IDE\libraries\DogLcdSPI\DogLcdSPI.cpp:291: error: 'SPI' was not declared in this scope
C:\Portable Apps\Arduino IDE\libraries\DogLcdSPI\DogLcdSPI.cpp: In member function 'void DogLcdSPI::writeCommand(int, int)':
C:\Portable Apps\Arduino IDE\libraries\DogLcdSPI\DogLcdSPI.cpp:298: error: 'SPI' was not declared in this scope
/*
  DogLcd Library - Hello World
 
  Demonstrates the basic use of a DOGM text LCD display.
  This sketch prints "Hello World!" to the LCD
  and shows the time.
 
  See the online-documention for wiring instuctions
  We assume  the following pins are connected:
  * LCD SI pin on MOSI Hardware SPI
  * LCD CLK pinon SCK Hardware SPI
  * LCD RS pin to digital pin 24
  * LCD CSB pin to digital pin 25
  * LCD RESET pin is not used
  * LCD Backlight pin is not used
 

*/

// include the library code:
#include <SPI.h>
#include <DogLcdSPI.h>

// initialize the library with the numbers of the interface pins
// Pins für RS und CSB
DogLcdSPI lcd(24, 25);

void setup() {

SPI.begin();

  // set up the LCD type and the contrast setting for the display 
  lcd.begin(DOG_LCD_M162);
  // Print a message to the LCD.
  lcd.print("hello, world!");
}

void loop() {
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);
  // print the number of seconds since reset:
  lcd.print(millis()/1000);
}

Was fehlt? Was ist falsch?

DogLcdSPI.rar (6.71 KB)

Da kann ich dem Compiler nur zustimmen:
In DogLcdSPI.cpp ist SPI nicht definiert.
( Wie wärs mit einem #include <SPI.h> )

Hallo,

michael_x:
Da kann ich dem Compiler nur zustimmen:
In DogLcdSPI.cpp ist SPI nicht definiert.
( Wie wärs mit einem #include <SPI.h> )

ne kannste nicht. Denn das habe ich gemacht. Er meckert auch rum wenn ich das #include <SPI.h> statt in den Haupt-Sketch in die .cpp Datei schreibe.

In dem angehängten rar File hat's jedenfalls gefehlt ...

Und der Compiler hat nun mal recht, das ist zwar ungerecht, aber so sind die Spielregeln :wink:

Er meckert auch rum wenn ich das #include <SPI.h> statt in den Haupt-Sketch in die .cpp Datei schreibe.

Und wenn Du’s in beide rein machst? Die IDE macht lustige Sachen mit dem Source-Code bevor sie es dem Compiler vorwirft, weshalb manchmal solche Workarounds nötig sind.

Hallo,

Danke. wenn ich das in beide Dateien schreibe kompiliert er ohne Gemecker. :slight_smile: Ist wirklich seltsam.
Muß dann noch ein "SPI.begin();" in den Hauptsktech > setup() oder nicht?

Muß dann noch ein “SPI.begin();” in den Hauptsktech > setup() oder nicht?

In DogLcdSPI::begin() fehlt es jedenfalls,
und irgendwann vor dem ersten SPI.transfer() sollte es schon gewesen sein.

Wie hat Eberhard Fahle e.fahle@wayoda.org sich das gedacht ?
Dafür ist das example\HelloWorld.pde ja wohl gemacht …

Hallo,

also muß es wo rein. Okay. Danke.

Bevor Du jedoch was verwechselst. Das Bsp. Hell World ist ja nur kopiert. Ich habe die gesamte Library DogLcd als Grundlage genommen und möchte diese auf die Nutzung mit Hardware SPI umbauen. Dazu habe ich erstmal um spätere Verwechslungen auszuschließen erstmal sämtliche Namen geändert und SPI rangehangen. Aus DogLcd wurde dann DogLcdSPI usw.

Hallo,

nachdem ich einen selbst eingebauten Fehler gefunden habe, Kabel von RS und CSB hatte ich vertauscht, funktioniert das nun tatsächlich. :slight_smile: Vielen Dank für die Hilfe.

Die Wartezeit nach einem Befehl habe ich bei 30µs belassen. Die 4MHz der SPI Schnittstelle sollten darauf keinen Einfluss haben, denke ich.

Allerdings sind nun neue Frage entstanden durch die Beschäftigung mit Librarys bzw. komme ich etwas durcheinander.

Wenn ich ein anderes Gerät am SPI ansprechen möchte, muß ich dann vorher nach Nutzung vom aktuellen Gerät ein SPI.end() verwenden?

Und warum erfolgt der Aufruf einer Funktion die in der Library steckt mit einem anderen Namen?

In der .h Datei steht zum Bsp. die Funktion so drin:

DogLcdSPI(int lcdRS, int lcdCSB, int lcdRESET=-1, int backLight=-1);

In der .cpp steht sie so drin.

DogLcdSPI::DogLcdSPI(int lcdRS, int lcdCSB, int lcdRESET, int backLight) {
    this->lcdRS=lcdRS;
    this->lcdCSB=lcdCSB;
    this->lcdRESET=lcdRESET;
    this->backLight=backLight;
}

jedoch im Haupt Sketch wird sie einfach mit lcd ... aufgerufen und nicht nur mir DogLcdSPI. Warum das?
DogLcdSPI lcd(24, 25);

Die anderen Aufrufe beginnen nur mit lcd. ... wie die hier zum Bsp.

lcd.begin(DOG_LCD_M162);
lcd.print("hello, world!");
lcd.setCursor(0, 1);

Bei anderen Funktionen steht ein void davor und bei anderen nicht. :roll_eyes:
Ich dachte eine Funktion muß bei ihrer Deklaration immer ein void haben.

Könnte mir das jemand erklären? Oder einen Link zu einer guten Beschreibung geben?

Das ist keine einfache Funktion, sondern der Konstruktor der Klasse:

http://www.cpp-tutor.de/cpp/le10/ctor_dtor.html

Ich dachte eine Funktion muß bei ihrer Deklaration immer ein void haben.

Nein. Void heißt lediglich dass die Funktion nichts zurückgibt. Du kannst auch andere primitive Datentypen zurückgeben.

Konstruktoren haben aber keinen Rückgabe-Wert

Hallo,

vielen Dank. Lese ich mir durch.