PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : LCD 2004 20x4 Zeichen per C/C++ für Raspi?



HaWe
04.08.2016, 00:03
hallo,

hat wer eine Idee,wie man so ein LCD Display mit HD44780 und i2c Controller
https://www.amazon.de/mn/search/?_encoding=UTF8&linkCode=ur2&camp=1634&creative=19450&tag=754-21&field-keywords=HD44780%20Display
per Raspi im C-Programm ansteuern kann? Man findet immer nur jede Menge Python...:
http://tutorials-raspberrypi.de/hd44780-lcd-display-per-i2c-mit-dem-raspberry-pi-ansteuern/

es soll ähnlich gehen wie bei Arduino:

Cursor setzen auf Zeile,Spalte, z.B.
LCD.setCursor(2,0);
dann String schreiben, z.B.
LCD.print(strbuf);

oder, alternativ, auch
lcdprintxy(x, y, strbuf);

kennt wer eine solche oder eine ähnliche lib?

piggituX
05.08.2016, 10:02
bei Sunfounder gibt es ein RaspiKit, da gibt ein C Beispiel für ein 16x2 aber direkt angeschlossen und lcd.h + wiringpi .... vielleicht kannst du da was von abwandeln und für dich benutzen.

HaWe
05.08.2016, 11:43
hallo,
vielen Dank, aber die dPin-Verkabelung verbraucht zu viele GPIOs, deshalb bin ich auf das i2c Gerät gekommen. WiringPi ist dazu schon ein guter Ansatz, das verwende ich sonst auch, nur müsste dann auch dafür eine i2c Lib oder aber der genaue i2c-Code-Ansteuerungscode samt high-level API-Befehlen existieren, eben vergleichbar mit Arduino/Wiring.

- - - Aktualisiert - - -

ps,
alternativ käme sogar auch ein kleines i2c-OLED Display in Frage wie das hier,
http://www.ebay.de/itm/1-3-SPI-I2C-IIC-128X64-OLED-LCD-LED-Display-Module-Board-For-Arduino-UNO-R3-STM-/291761970039?hash=item43ee5e5b77:g:UOsAAOSwHJhXM-pJ
aber auch dazu wäre eine i2c-Lib (z.B. für wiringPi) notwendig -
und auch Adafruit z.B. bietet nur Python, keine C/C++ libs soweit ich es durchforstet habe:
https://learn.adafruit.com/adafruit-oled-displays-for-raspberry-pi/programming-your-display
(Das Adafruit OLED ist allerdings SPI wie es aussieht, kein I2C)

HaWe
04.09.2016, 16:14
update:
habe mich jetzt für das 128x64 OLED entschieden - ist klein, flach, hat bis zu 8 Zeilen zu je 21 Zeichen, 3 verschiedene Schriftgrößen, und läuft im Gegensatz zu den PCF8574-i2c- getriebenen LCD2004 auch gemeinsam mit anderen i2c Geräten bei 400kHz!

Hier ein Testbeispiel, das ich grade für i2c-Testzwecke (RTCDS3231 plus OLED bei 400kHz) geschrieben habe - funktioniert perfekt. Später kommen sowohl der Display-Teil als auch andere langsame Geräte-Zugriffe (RTC, ...) in je einen eigenen low-priority pthread task, damit sie die schnellen Geräte (MCP23017, IMU etc.) nicht durch delays behindern - share and enjoy!


/*
*
* RTC DS3231
* plus OLED Display
*
* ver 0001
*
*/


#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>

#include <stdbool.h>
#include <string.h>
#include <termio.h>

#include <wiringPi.h>
#include <wiringPiI2C.h>

#include <ArduiPi_OLED_lib.h>
#include <Adafruit_GFX.h>
#include <ArduiPi_OLED.h>
#include <getopt.h>


#define byte uint8_t

// RTC DS3231
#define ADDR_RTCDS3231 0x68
int fRTCds3231;

// Instantiate the OLED display
ArduiPi_OLED display;


void oled_cls() {
display.clearDisplay();
display.display();
}


void oled_printxy(int x, int y, char * str) {
display.setCursor(x,y);
display.print(str);
display.display();
}


void oled_clrlnxy(int x, int y) {
display.setTextColor(BLACK, BLACK);
oled_printxy( 0, 8, " ");
display.setTextColor(WHITE, BLACK);
}


// mimic conio.h kbhit
bool kbhit(void)
{
struct termios original;
tcgetattr(STDIN_FILENO, &original);
struct termios term;
memcpy(&term, &original, sizeof(term));
term.c_lflag &= ~ICANON;
tcsetattr(STDIN_FILENO, TCSANOW, &term);
int characters_buffered = 0;
ioctl(STDIN_FILENO, FIONREAD, &characters_buffered);
tcsetattr(STDIN_FILENO, TCSANOW, &original);
bool pressed = (characters_buffered != 0);
return pressed;
}

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


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


//================================================== ===================================




void setDS3231time( byte year, byte month, byte day,
byte hour, byte minute, byte second, byte dow)
{
// sets time and date data to DS3231

wiringPiI2CWriteReg8(fRTCds3231, 0, decToBcd(second)); // set seconds
wiringPiI2CWriteReg8(fRTCds3231, 1, decToBcd(minute)); // set minutes
wiringPiI2CWriteReg8(fRTCds3231, 2, decToBcd(hour)); // set hours
wiringPiI2CWriteReg8(fRTCds3231, 3, decToBcd(dow)); // ( 1=Sunday, 7=Saturday)
wiringPiI2CWriteReg8(fRTCds3231, 4, decToBcd(day)); // set dayOfMonth (1 to 31)
wiringPiI2CWriteReg8(fRTCds3231, 5, decToBcd(month)); // set month
wiringPiI2CWriteReg8(fRTCds3231, 6, decToBcd(year)); // set year (0 to 99)

}


void getDS3231time( int &year, int &month, int &day,
int &hour, int &minute, int &second, int &dow)
{
second = bcdToDec(wiringPiI2CReadReg8 (fRTCds3231, 0) & 0x7f );
minute = bcdToDec(wiringPiI2CReadReg8 (fRTCds3231, 1) );
hour = bcdToDec(wiringPiI2CReadReg8 (fRTCds3231, 2) & 0x3f );
dow = bcdToDec(wiringPiI2CReadReg8 (fRTCds3231, 3) );
day = bcdToDec(wiringPiI2CReadReg8 (fRTCds3231, 4) );
month = bcdToDec(wiringPiI2CReadReg8 (fRTCds3231, 5) );
year = bcdToDec(wiringPiI2CReadReg8 (fRTCds3231, 6) );
}


char * sdow (int dow) {
switch(dow){
case 1:
return("Sunday");
break;
case 2:
return("Monday");
break;
case 3:
return("Tuesday");
break;
case 4:
return("Wednesday");
break;
case 5:
return("Thursday");
break;
case 6:
return("Friday");
break;
case 7:
return("Saturday");
break;
}
return ("error");

}

//================================================== ===================================



int main() {
static int year, month, day, hour, minute, second, dow;
int i=0, check;
char sbuf[100];

// Oled supported display in ArduiPi_SSD1306.h

// I2C change parameters to fit to your LCD
if ( !display.init(OLED_I2C_RESET, 6) )
exit(EXIT_FAILURE);

display.begin();

// init done

oled_cls();

// test

display.setTextSize(1);
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(0, 0); display.print(" 0 Hello, world!\n");
display.setCursor(0, 8); display.print(" 8 i2c OLED");
display.setCursor(0,16); display.print("16 128x64 addr 0x3c");
display.setCursor(0,24); display.print("24 8x21 char size=1");
display.setCursor(0,32); display.print("32 ");
display.setCursor(0,40); display.print("40 ");
display.setCursor(0,48); display.print("48 456789112345678921");
display.setCursor(0,56); display.print("56 ");
//display.setTextColor(BLACK, WHITE); // 'inverted' text
display.display();
sleep(1);
oled_cls();


// fRTCds3231 = wiringPiI2CSetupInterface( "/dev/i2c-0", ADDR_RTCDS3231 );
fRTCds3231 = wiringPiI2CSetupInterface( "/dev/i2c-1", ADDR_RTCDS3231 );

strcpy(sbuf, "RTC DS3231 \n\n");
printf(sbuf);
oled_printxy( 0, 0, sbuf);
getDS3231time( year, month, day, hour, minute, second, dow);
sprintf(sbuf, "20%02d/%02d/%02d %02d:%02d:%02d", year, month, day, hour, minute, second);
printf(sbuf);
oled_printxy( 0, 8, sbuf);
sprintf(sbuf, " Day of week %1d: ", dow);
printf(sbuf);
printf(sdow(dow) );
printf("\n\n");

printf("*** Set Date/Time: enter 1 *** \n");
printf("*** else: display time *** \n\n");
oled_printxy( 0,24, "Set DateTime enter 1");
oled_printxy( 0,32, "else: display time");

i = getchar();

//debug
//printf("%d \n", i);

while (i=='1') {
// get string yy mm dd hh mm ss dw : gets() ?
printf("yy mm dd hh mm ss dw (DayOfWeek) \n");
check=scanf("%d %d %d %d %d %d %d", &year, &month, &day, &hour, &minute, &second, &dow);

getchar();
printf("check=%d\n", check);

if(check==7) {
sprintf(sbuf, "20%02d/%02d/%02d %02d:%02d:%02d", year, month, day, hour, minute, second);
printf(sbuf);
oled_printxy( 0, 8, sbuf);
printf(" Day of week %1d: ", dow);
printf(sdow(dow) );
printf("\n");
setDS3231time( year, month, day, hour, minute, second, dow );
}

oled_cls();

printf("RTC DS3231 \n");
oled_printxy( 0, 0, sbuf);
printf("*** Set Date/Time: enter 1 *** \n");
printf("*** else: display time *** \n\n");
oled_printxy( 0,24, "Set DateTime enter 1");
oled_printxy( 0,32, "else: display time");
i=0;
i = getchar();

}

oled_cls();
oled_printxy( 0, 0, "RTC DS3231 - quit:ESC");

while(1) {
getDS3231time( year, month, day, hour, minute, second, dow);
sprintf(sbuf, "20%02d/%02d/%02d %02d:%02d:%02d", year, month, day, hour, minute, second);
printf(sbuf);
oled_clrlnxy( 0,16);
oled_printxy( 0,16, sbuf);
printf(" Day of week %1d: ", dow);
printf(sdow(dow) );
printf("\n");
if (kbhit())
{
int c = getchar();
if(c==27) break;
}
sleep(1);
}

oled_cls();
return (0);
}