Forum: Mikrocontroller und Digitale Elektronik I2C Bus und Sonderzeichen


von Achim S. (achims)


Lesenswert?

Hallo Gemeinde
Ein Sonderzeichen kann ich mit den folgenden Stück Code machen:
1
static const PROGMEM unsigned char sonder1[] = // Daten für sonder1
2
  {
3
    0x04, 0x0e, 0x1f, 0x04, 0x04, 0x04, 0x04, 0x00,  // Zeichen 1 hoch 
4
    0x00, 0x10, 0x09, 0x05, 0x03, 0x0f, 0x00, 0x00,  // Zeichen 2 Enter
5
    0x00, 0x04, 0x04, 0x04, 0x04, 0x1f, 0x0e, 0x04,  // Zeichen 3 unten
6
    0x15, 0x0e, 0x15, 0x0e, 0x04, 0x04, 0x04, 0x0e,  // Zeichen 4 Sendeturm 
7
    0x04, 0x0a, 0x11, 0x1f, 0x11, 0x11, 0x1f, 0x00,  // Zeichen 5 Haus  
8
    0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1f,  // Zeichen 6 Ecke links
9
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x1f,  // Zeichen 7 Ecke rechts
10
    0x0e, 0x1f, 0x0e, 0x11, 0x0e, 0x11, 0x0e, 0x00   // Zeichen 8 HDD
11
  };
Im Programm kann ich es mit
1
lcd_putc(0);     // Ausgabe Zeichen 1 
2
lcd_putc(1);     // Ausgabe Zeichen 2
ausgeben:
Wie kann ich diese Zeichen im I2C Bus einbinden bzw. aufrufen?
Dort schreibe ich ja erst:
1
    i2c_init();                      // Starte I2C Bus
2
    lcd_init();                      // Starte I2CLCD
und dann später
1
lcd_printlc(1,1,"Die 1. Zeile");    // Text Zeile 1

achim

von Karl H. (kbuchegg)


Lesenswert?

Achim Seeger schrieb:


> und dann später
>
1
> lcd_printlc(1,1,"Die 1. Zeile");    // Text Zeile 1
2
>

nichts und niemand hindert dich daran den Text auf mehrmals auszugeben 
und dzwischen dann das Sonderzeichen einzustreuen
1
   lcd_printlc( 1, 1, "Die 1" );
2
   lcd_printchar( 6, 1, 4 );   // Sonderzeichen 4
3
   lcd_printlc( 7, 1, " Zeile" );

wenn du dir dafür noch eine Spezialfunktion machen musst, die ein 
einzelnes Byte ausgibt, dann wirst du das wohl machen müssen. Aber 
eigentlich dürftest du diese Funktion schon haben, weil sich sehr 
wahrscheinlich die Funktion zur Stringausgabe darauf stützt.

Du kannst dir auch im Vorfeld den String schon mit dem Sonderzeichen 
zusammenbauen, wobei du allerdings mit dem Zeichen mit dem Code 0 
Schwierigkeiten kriegst, weil diese 0 per Definition das Ende eines 
Strings anzeigt, was wohl die Funktion zur Stringausgabe ausser Tritt 
bringen wird.
Aber die anderen Zeichen gehen. Einfach mal in deinem Lehrbuch 
nachsehen, wie man in einem String Zeichen durch ihre Codezahl angibt.

: Bearbeitet durch User
von Falk B. (falk)


Lesenswert?

@ Achim Seeger (achims)

>Wie kann ich diese Zeichen im I2C Bus einbinden bzw. aufrufen?

Gar nicht, denn das interessiert den I2C nicht eine Sekunde. Aber das 
LCD, das am I2C hängt, schon eher.

>lcd_printlc(1,1,"Die 1. Zeile \x1");    // Text Zeile 1, am Ende Sonderzeichen 1

\x ist eine Escapsequenz für ASCII-Zeichen mit Angabe des HEX-Codes.
\x41 ist der ASCII-Code für A.
Wenn rundherum aber die Zeichen 0-9 bzw a-F direkt folgen, muss man 
etwas Tricksen.

lcd_printlc(1,1,"Der Test " "\x2" "a.")

Dabei werden die Einzelstrings zwar erstmal einzeln bewertet und die 
Escapesequenz RICHTIG interpreztiert, OHNE das abschließende a.

von Achim S. (achims)


Lesenswert?

Danke Karl Heinz
irgendwie habe ich mir das schwieriger vorgestellt. Mache zwar viel mit 
dem Bus, lerne aber ständig dazu. Das kennst du ja von mir.
Werde es testen und hier berichten.
achim

von Achim S. (achims)


Lesenswert?

Hallo
Ich habe die Teile in mein Programm eingebaut. Es sieht jetzt so aus:
1
static const PROGMEM unsigned char sonder1[] =  // Daten für sonder1
2
  {
3
    0x04, 0x0e, 0x1f, 0x04, 0x04, 0x04, 0x04, 0x00,  // Zeichen 1 hoch
4
    0x00, 0x10, 0x09, 0x05, 0x03, 0x0f, 0x00, 0x00,  // Zeichen 2 Enter
5
    0x00, 0x04, 0x04, 0x04, 0x04, 0x1f, 0x0e, 0x04,  // Zeichen 3 unten
6
    0x15, 0x0e, 0x15, 0x0e, 0x04, 0x04, 0x04, 0x0e,  // Zeichen 4 Sendeturm
7
    0x04, 0x0a, 0x11, 0x1f, 0x11, 0x11, 0x1f, 0x00,  // Zeichen 5 Haus
8
    0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1f,  // Zeichen 6Ecke links
9
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x1f,  // Zeichen 7Eckerechts
10
    0x0e, 0x1f, 0x0e, 0x11, 0x0e, 0x11, 0x0e, 0x00  // Zeichen 8 HDD
11
  };
12
13
int main(void)
14
  {
15
    unsigned char i;     // Varaible i  
16
    i2c_init();         // Starte I2C Bus
17
    lcd_init();         // Starte I2CLCD
18
    lcd_light(0);  // 0=Licht an, 1=Licht aus
19
  
20
    for (;;)
21
      {
22
        lcd_command(_BV(LCD_CGRAM));    // Daten laden
23
        for(i=0; i<64; i++)    // 64 x
24
          {
25
            lcd_data(pgm_read_byte_near(&sonder1[i]));// schreiben der Daten in den CG RAM
26
          }

Wenn ich es dann starte bekomme ich so ca 50 Fehlermeldungen. Als erstes 
gleich dabei, das lcd.h fehlt
Welche brauche ich den? Die lcd.h oder die I2clcd.h?
Die Ausgabe über den Bus ist wie oben.
Sorry, das versteh ich jetzt nicht mehr.
achim

von holger (Gast)


Lesenswert?

>Wenn ich es dann starte bekomme ich so ca 50 Fehlermeldungen. Als erstes
>gleich dabei, das lcd.h fehlt

Ja, wo ist sie denn? Vieleicht mal nen Pfad mit angeben oder
ins Projekt einfügen?


Und du willst doch nicht wirklich mit jedem Mainloop Durchlauf
die Sonderzeichen setzen? Einmal am Beginn des Programms reicht völlig.

von Achim S. (achims)


Lesenswert?

Du hast recht Holger, einmal reicht, hab es gleich geändert.
Sorry, eine flasche angabe gemacht. Gebe ich die lcd.h, dann bekomme ich 
ca. Fehlermeldungen. Ohne Angabe habe ich nur 4 Meldungen. Auch mit 
diesen nur "4" Meldungen komme ich nicht klar, da ich nicht weiss, was 
er von mir will.
achim

von holger (Gast)


Lesenswert?

>Ohne Angabe habe ich nur 4 Meldungen.

Dann solltest du diese 4 Meldungen auch mal bekannt geben;)

von Achim S. (achims)


Lesenswert?

Sorry, habe eben noch mal ins Programm geschaut. Rufe die Sonderzeichen 
nur einmal beim start auf, while kommt erst später

von Achim S. (achims)


Lesenswert?

Kein Problem, kommt sofort

Warning  3  implicit declaration of function 'lcd_data' 
[-Wimplicit-function-declaration]  E:\AAA 
Technik\Roboter\RN-Controll\RNC 
Programme\ATB_B1_Display_2\ATB_B1_Display_2\ATB_B1_Display_2.c  45  8 
ATB_B1_Display_2

Error  4  expected declaration or statement at end of input  E:\AAA 
Technik\Roboter\RN-Controll\RNC 
Programme\ATB_B1_Display_2\ATB_B1_Display_2\ATB_B1_Display_2.c  78  1 
ATB_B1_Display_2

Warning  2  each undeclared identifier is reported only once for each 
function it appears in  E:\AAA Technik\Roboter\RN-Controll\RNC 
Programme\ATB_B1_Display_2\ATB_B1_Display_2\ATB_B1_Display_2.c  42  19 
ATB_B1_Display_2

Error  1  'LCD_CGRAM' undeclared (first use in this function)  E:\AAA 
Technik\Roboter\RN-Controll\RNC 
Programme\ATB_B1_Display_2\ATB_B1_Display_2\ATB_B1_Display_2.c  42  19 
ATB_B1_Display_2

von holger (Gast)


Lesenswert?

>Sorry, habe eben noch mal ins Programm geschaut. Rufe die Sonderzeichen
>nur einmal beim start auf, while kommt erst später

Na super. Du zeigst uns nicht deinen Code sondern irgendwas.
Irgendwie sinkt meine Bereitschaft dir zu helfen gerade
ins Bodenlose.

von Achim S. (achims)


Lesenswert?

Der ganze Code (alles)
1
#include <stdbool.h>
2
#include <avr/pgmspace.h>
3
#include "main.h"
4
#include <util/delay.h>
5
#include "i2clcd.h"
6
#include "i2cmaster.h"
7
#include "avr/io.h"
8
#include "lcd.h"            // Aufruf lcd.h
9
10
static const PROGMEM unsigned char sonder1[] =    // Daten für sonder1
11
{
12
  0x04, 0x0e, 0x1f, 0x04, 0x04, 0x04, 0x04, 0x00,    // Zeichen 1 hoch
13
  0x00, 0x10, 0x09, 0x05, 0x03, 0x0f, 0x00, 0x00,    // Zeichen 2 Enter
14
  0x00, 0x04, 0x04, 0x04, 0x04, 0x1f, 0x0e, 0x04,    // Zeichen 3 unten
15
  0x15, 0x0e, 0x15, 0x0e, 0x04, 0x04, 0x04, 0x0e,    // Zeichen 4 Sendeturm
16
  0x04, 0x0a, 0x11, 0x1f, 0x11, 0x11, 0x1f, 0x00,    // Zeichen 5 Haus
17
  0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1f,    // Zeichen 6 Ecke links
18
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x1f,    // Zeichen 7 Ecke rechts
19
  0x0e, 0x1f, 0x0e, 0x11, 0x0e, 0x11, 0x0e, 0x00    // Zeichen 8 HDD
20
};
21
22
int main(void)
23
{
24
      unsigned char i;               // Varaible i  
25
  
26
  i2c_init();                      // Starte I2C Bus
27
  lcd_init();                      // Starte I2CLCD
28
  lcd_light(0);            // 0=Licht an, 1=Licht aus
29
  
30
      for (;;)
31
      {
32
        lcd_command(_BV(LCD_CGRAM));        // Daten laden
33
        for(i=0; i<64; i++)            // 64 x
34
        {
35
          lcd_data(pgm_read_byte_near(&sonder1[i]));    // schreiben der Daten in den CG RAM
36
        }
37
  
38
  // Display Befehle
39
  lcd_command(LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKINGOFF);
40
  // Display ON/OFF / Cursor ON/OFF / Blinken ON/OFF
41
  
42
  lcd_command(LCD_CLEAR);            // Leere Display
43
  _delay_ms(2);              // warte 2ms
44
  
45
  lcd_printlc(1,6,"vvvvvvv");         // Text Zeile 1
46
  lcd_printlc(2,2,"**************");    // Text Zeile 2
47
  lcd_printlc(3,2,"Display Modul 1");    // Text Zeile 3
48
  lcd_printlc(4,2,"(by achim S.)");    // Text Zeile 4
49
  _delay_ms(5000);                 // Warte 5000ms
50
  
51
  while(1)
52
  {
53
    lcd_command(LCD_CLEAR);            // Leere Display
54
    _delay_ms(1000);                // Warte 20ms
55
    
56
    lcd_printlc(1,1,"Die 1. Zeile");  // Text Zeile 1
57
    _delay_ms(2000);          // warte 2s
58
    
59
    lcd_printlc(2,2,"Die 2. Zeile");  // Text Zeile 2
60
    _delay_ms(2000);          // warte 2s
61
    
62
    lcd_printlc(3,3,"Die 3. Zeile");  // Text Zeile 3
63
    _delay_ms(2000);          // warte 2s
64
    
65
    lcd_printlc(4,4,"Die 4. Zeile");  // Text Zeile 4
66
    _delay_ms(5000);          // warte 5s
67
  }
68
}

von holger (Gast)


Lesenswert?

>Warning  3  implicit declaration of function 'lcd_data'

Da fehlt ein #include "lcd.h"

Immer die erste Fehlermeldung beseitigen.
Die nachfolgenden erst mal ignorieren.
Der Rest der Fehler verschwindet dann möglicherweise von alleine.

von holger (Gast)


Lesenswert?

1
      for (;;)
2
      {
3
        lcd_command(_BV(LCD_CGRAM));        // Daten laden
4
        for(i=0; i<64; i++)            // 64 x
5
        {
6
          lcd_data(pgm_read_byte_near(&sonder1[i]));    // schreiben der Daten in den CG RAM
7
        }
8
// Hier fehlt eine schliessende Klammer!

von holger (Gast)


Lesenswert?

Verdammt;)

Was soll das for da?
Da kommst du nie wieder raus!

      for (;;)
      {

von Achim S. (achims)


Lesenswert?

In der Datei i2clcd.h oder c habe ich die Angabe zu dem Display vom Bus. 
Mit Angabe der Pin nr. Anschluss PCF 8574, Speicher usw. In der Datei 
lcd.h oder c habe ich auch die Angabe vom Display drin. Gebe ich das 
frei bekomme ich 13 Meldungen uner anderem auch das

Error  9  conflicting types for 'lcd_init'  E:\AAA 
Technik\Roboter\RN-Controll\RNC 
Programme\ATB_B1_Display_2\ATB_B1_Display_2\lcd.h  187  13 
ATB_B1_Display_2

Da ich alles über den Bus betreibe, bin ich jetzt so richtig 
durcheinander

von Achim S. (achims)


Lesenswert?

Habe beide Sachen auskommentiert, bleibt das gleiche

von Achim S. (achims)


Lesenswert?

Das Display wird doch jetzt über den I2C Bus angesteuert. Muss nicht die 
Sonderzeichen auch über den Bus auf das Display geladen werden? Verwende 
ich dabei den gleichen Befehl, als wenn das Display direkt am Prozessor 
hängt?

von holger (Gast)


Lesenswert?

>Habe beide Sachen auskommentiert, bleibt das gleiche

Pack das komplette Projektverzeichnis in eine ZIP Datei
und poste die hier.

Das wird sonst nichts.

von Achim S. (achims)


Angehängte Dateien:

Lesenswert?

Das ganze Paket mit allen Sachen

von Achim S. (achims)


Lesenswert?

Sorry, für heute melde ich mich, um 4 klingelt der wecker

von holger (Gast)


Lesenswert?

>Sorry, für heute melde ich mich, um 4 klingelt der wecker

Dann kannst du ja morgen aufräumen.

Du hast ZWEI LCD Librarys gemischt.
Das kann nicht gehen.

von Achim (Gast)


Lesenswert?

Morgen
wenn ich die I2Clcd benutze bekomme ich die 4 Fehlermeldungen. Nutze ich 
die lcd zusätzlich bekomme ich 13 Fehlermeldungen.
Ein paar Fragen dazu.
Ich nutze das Display im 4 Bit Modus mit einer Ansteuerung über den PCF 
8574. Dazu schreibe ich Daten auf das Display.
Muss ich das nicht genau so machen, wenn ich den Speicher des Displays 
beschreibe?

von Falk B. (falk)


Lesenswert?

@Achim (Gast)

>Ich nutze das Display im 4 Bit Modus mit einer Ansteuerung über den PCF
>8574. Dazu schreibe ich Daten auf das Display.

Achim, du lernst es nie.

Beitrag "Re: I2CLCD Library für HD44780 LCDs"

Einfacher geht es nicht. Eien Funktion zur Definitin der eigenen Zeichen 
gibt es auch schon, muss man nur aufrufen. Und du macht immer wieder den 
selben, chaotischen Unsinn. Tu dir selber einen Gefallen und such dir 
ein anderes Hobby.

von achim (Gast)


Lesenswert?

Stimmt, du hast Recht.
In meinem hohem Alter wird man schon vergesslich. Sorry. Noch nicht 
senil, aber knapp da vor.
Ein ganzen Teil habe ich schon verwendet, doch diese Stelle habe ich da 
wohl zu schnell gelesen. Bin ja lernfähig und nicht beratugsresident.
Da danke ich für deine Info
achim

von Achim S. (achims)


Lesenswert?

Hallo Falk
habe mir dein ganzes Programm noch mal vorgenommen. War blöd, das ich so 
lange was anderes gemacht habe. Bekomme fast alles zum laufen, fast 
alles.
Du schreibst:
1
// user char, euro symbol
2
const char my_char1[] PROGMEM = {0x06, 0x09, 0x10, 0x0E, 0x10, 0x09, 0x06, 0x00};
und dann weiter
1
// define user character
2
  lcd_def_char(my_char1, 7);
bei lcd_def_char bekomme ich eine Fehlermeldung. Nach Angabe von AVR 
Studio kennt er das nicht.
achim

von Joachim B. (jar)


Lesenswert?

Achim Seeger schrieb:
> und dann weiter// define user character
>   lcd_def_char(my_char1, 7);
> bei lcd_def_char bekomme ich eine Fehlermeldung. Nach Angabe von AVR
> Studio kennt er das nicht.
> achim

kein Wunder, weil du dem Link von Falk nicht gefolgt bist:

Beitrag "Re: I2CLCD Library für HD44780 LCDs"

http://www.mikrocontroller.net/attachment/221306/i2clcd.zip

dort ist es doch drin und wenn du das nicht nimmst, woher soll er das 
kennen ?

von Achim S. (achims)


Lesenswert?

Habe es gefunden und eingebaut. Jetzt habe ich ein paar andere 
Veränderungen, Suche gerade warum

von Achim S. (achims)


Angehängte Dateien:

Lesenswert?

So, habe den Artikel von Falk gründlich gelesen und befolgt. Ein paar 
Sachen sind noch unklar. Das meiste habe ich wohl verstanden.
Daraus ist ein Programm entstanden, was so ziemlich alles berücksichtigt 
bzw. nutzt. Es werden auch die Datein von Falk dazu verwendet. Habe erst 
später gesehen, was Falk alles verändert hat und für was es genutzt 
wird.
Hänge das Prg an, damit jeder Leser oder Sucher das gleiche machen kann.
Danke an die Helfer und die Geduldigen mit mir.
Das Prg arbeite mit einem AT1284p, 16MHz, I2C-Bus, Display TC1604
achim

von Falk B. (falk)


Lesenswert?

@ Achim Seeger (achims)

>    ATB_Prg_Display_2.pdf | anzeigen

Mensch Achim, bist du schon wieder neu in diesem Forum?
Seit wann werden Quelltexte als PDF gespeichert?

Das Programm ist zwar recht rivial, aber sei's drum. Wenn du noch die 
Funktion

Zeichen_def(); // Definiert Sonderzeichen

VOR der Endlosschleife aufrufen würdest, wäre es ein Schritt in die 
richtige Richtung. Den die muss man nur EINMAL definieren, nicht immer 
wieder.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Achim Seeger schrieb:
> Hänge das Prg an, damit jeder Leser oder Sucher das gleiche machen kann.

 Deine Kommentare zu Strings sind sehr hilfreich.
 Nicht böse sein. ;-D

von Achim S. (achims)


Lesenswert?

Stimmt, du hast recht. Habe wie üblich was falsch drin. Leider diese 
Stelle total übersehen. Danke für deinen Tip. Bemühe mich nach Kräften.
Eine Frgae bleibt, die ich nicht beantworten konnte. Vielleicht kannst 
du mir einen Tip geben.
Hatte bei einem anderen Display (kein I2C) von KH die Info bekommen, wie 
man 3 verschieden Sonderzeichen zu jeweils 8 Stück machen kann. Es steht 
irgendwo im Netz.
Dort hat er jeweils 8 Sonderzeichen als 1 Array deklariert und jeweils 
das nötige aufgerufen.
Das klappt hier aber nicht. Bekomme es nicht als Array aufgebaut oder 
gespeichert.
Die Idee dahinter ist, rufe jeweils mit void Sonder1 oder 2 oder 3 auf, 
lade die Zeichensätze dazu und nehme nur dieses dazu. Sorry, weis nicht 
wie ich es besser erklären kann. Suche nach dem Info von KH. Vielleicht 
finde ich es.
Noch was, könnte den Code auch als c reinstellen. Sind aber so ca 2 bis 
3 Seiten. Ist das nicht zu lang?
achim

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.