Hallo,
ich würde gerne ein Bild mit 1 Bit Farbtiefe auf einem 240x120 Display
ausgeben können.
Hierfür habe ich mir aus einem Bild ein Array in der Form
unsigned char logo[]=
{
...
}
Es handelt sich natürlich um das BMP Format und in dem Array befinden
sich nur die Farbinformationen (also kein Informations- oder Dateikopf).
Exakt hat das Bild 210x118 Pixel.
Zur Verfügung stehen mir eine
1
// Set page address 0~15
2
voidSet_Page_Address(unsignedcharadd)
3
voidSet_Column_Address(unsignedcharadd)
4
undeineFunktion,diedie8BitansDisplaysendet
5
voidWrite_Data(unsignedchardat)
Mir ist klar, dass ich dies irgendwie mit 2 For-Schleifen realisieren
muss, aber ich bekomme es nicht hin.
Ansatz:
Simon schrieb:> Hallo,>> ich würde gerne ein Bild mit 1 Bit Farbtiefe auf einem 240x120 Display> ausgeben können.>> Hierfür habe ich mir aus einem Bild ein Array in der Form>> unsigned char logo[]=> {> ...> }
und mit welcher Technik hast du die 2 Bild-Dimensionen auf 1
zusammengepackt?
Mit der Umkehrung davon musst du dann hier
> void print logo(unsigned char bild[])> {> unsigned char i,j;> for(i=0;i<15;i++)> {> ...> for(j=0;j<240;j++)> {> Write_Data(...);> }> }> return;> }
arbeiten, wenn nicht überhaupt deine Write_Data Funktion das Aufteilen
in Bytespalten schon erledigt.
Simon schrieb:> Mir ist klar, dass ich dies irgendwie mit 2 For-Schleifen realisieren> muss, aber ich bekomme es nicht hin.
Warum eine Schleife 0 bis 15?
Ich kenne dein Display nicht genau, aber soviel kann ich sagen:
Es wird vermutlich eine Farbtiefe von 16 oder 18 Bit (einstellbar)
haben, das bedeuted dass du für jedes Pixel 16 oder 18 Bit
schreiben musst. Für 16 Bit wäre Schwarz 0x0000 und weiss 0xFFFF.
Für 1 Bit Fabrtiefe kannst du dir also für dunkel und für hell
zwei "beliebige" 16 Bit Werte aussuchen die du schreibst.
Ansonsten sind diese Displays in Spalten und Zeilen aufgeteilt,
in deinem Fall 240x320. Diese gilt es explizit zu beschreiben.
Genaueres musst du deinem Datenblatt entnehmen, das heisst du
musst es lesn, verstehen und deine Schlussfolgerungen daraus
ziehen.
Ich habe das Bild in den Graphics Resource Converter von Microchip
gejagt. Write_Dat sieht wie folgt aus und sendet einfach nur 8 Bit:
1
voidWrite_Data(unsignedchardat)
2
{
3
ERC_CS_1;
4
ERC_CD_1;// Instruction auf 1 ziehen
5
SPI_Write(dat);
6
ERC_CS_0;
7
return;
8
}
Ich weiss nicht genau in welcher Reihenfolge der Konverter die Bits
herausgibt.
Was ich ja eigentlich will:
Erste Zeile -> 210 mal ein Pixel
Zweite Zeile -> 210 mal ein Pixel
...
118. Zeile -> 210 mal ein Pixel
Ich muss dann hoffen, dass der Konverter die Daten in genau dieser
Reihenfolge abgelegt hat.
Bis jetzt kommt nur "Unfug" heraus :)
Simon schrieb:> Mir ist klar, dass ich dies irgendwie mit 2 For-Schleifen realisieren> muss, aber ich bekomme es nicht hin.
So, du möchtest also ein Bild anzeigen, scheiterst aber bereits an zwei
simplen Schleifen.
Hmm..
Wäre es zuviel von dir verlangt, vielleicht erstmal die alleruntersten
Grundlagen des Programmierens zu erlernen?
Wenn du das gelernt hast, könntest du anschließend dir Gedanken über die
sogenannte Hardware machen, insbesondere darüber, was du denn
eigentlich für ein Display hast und wie es angesteuert sein will.
Über solche Dinge wie platzsparende RLE-Codierung von ansonsten zu
umfänglichen Bilddaten könntest du im Anschluß in der Lernbetty
nachlesen, ich hab's dort vorgeturnt, aber ich befürchte, daß dir das zu
mühsam ist.
Ähem.. gebratene Tauben gibt's im Schlaraffenlande.
W.S.
Simon schrieb:> ich würde gerne ein Bild mit 1 Bit Farbtiefe auf einem 240x120 Display> ausgeben können.
Ich habe mich verlesen und dachte 240x320 ...... aber 240x120 glaube
ich einfach nicht. Plausibel wäre 120x160 ??
isidor schrieb:> Ich hab net g'schaugt.
Dann mach das bitte in Zukunft, bevor du jemand anderen (indirekt) der
Lüge bezichtigst, okay? Es gibt viel mehr Dinge, als du glaubst...
npn schrieb:> bevor du jemand anderen (indirekt) der> Lüge bezichtigst
Nö, allerhöchstens des potentiellen Irrtums. Jeder kann
sich irren, auch du .....
isidor schrieb:> npn schrieb:>> bevor du jemand anderen (indirekt) der>> Lüge bezichtigst>> Nö, allerhöchstens des potentiellen Irrtums. Jeder kann> sich irren, auch du .....
Wir müssen uns doch hier nicht streiten. Ich weiß, daß sich jeder irren
kann. Aber in der Regel schau ich erstmal nach, ob ich entsprechende
Daten im Netz finde. Wenn ich dann nichts finde, kann ich das dem
anderen immer noch mitteilen. Aber ich sage nicht einfach, daß ich ihm
nicht glaube.
So, und jetzt ist dieses Thema beendet, weil das dem Simon nicht
weiterhilft, okay?
Simon schrieb:> ich würde gerne ein Bild mit 1 Bit Farbtiefe auf einem 240x120 Display> ausgeben können.
OK, soweit erstmal kein ungewöhnlicher Wunsch...
> Hierfür habe ich mir aus einem Bild ein Array in der Form>> unsigned char logo[]=> {> ...> }
Schon Scheiße, damit sind wohl mindestens sämtliche Metadaten des Bildes
wech'.
> Es handelt sich natürlich um das BMP FormatNEIN, genau das ist es dann mit absoluter Sicherheit nicht mehr.
> in dem Array befinden> sich nur die Farbinformationen (also kein Informations- oder Dateikopf)
Eben weil genau damit alle Metadaten des BMP-Formats wech' sind. Im
allerbesten Fall stehen in deinem Array wenigstens noch die
vollständigen Imagedaten des Monochrome-Bitplane. Nur ist das Problem:
ohne sie beschreibende Metadaten können sie da (mindestens) in zwei,
unter unterschiedlichen praktischen Aspekten durchaus gleichermaßen
sinnvollen Formaten rumliegen. Immer unter der Voraussetzung, daß
überhaupt was sinnvolles darin steht...
> Exakt hat das Bild 210x118 Pixel.
Böse, böse. 210 ist nicht ganzzahlig durch 16 teilbar. Das läßt eine
gewisse Wahscheinlichkeit erahnen, daß schon die Imagedaten in deinem
char-Array "korrupt" sind, denn leider gibt es viele
Freeware-Programmierer, die genausowenig Ahnung von Bildverarbeitung
haben wie du...
Also entweder verrätst du uns, wie du zu diesem Array gekommen bist oder
du zeigst es uns einfach mit den enthaltenen Daten, dann kann man die
nötigen Metadaten nämlich selber spielend leicht herausfinden, dank der
menschlichen Mustererkennungsfähigkeiten genügt dafür bei monochromen
Bitmaps meist sogar ein Hexeditor von der Stange. Wenn man denn weiß,
was man sehen soll und weiß, was man tut...
Ja mehr noch: im konkreten Fall würde es den BLICKIGEN wahrscheinlich
sogar reichen, wenn du wenigstens die Anzahl der chars in dem Array
verraten hättest. Aber selbst das war wohl schon zu geheim...
Das verät garnix über das Logo (nein, das bleibt dein Geheimnis, wir
sagen deinem Kunden nicht, wie unfähig du bist), aber bei den gegebenen
Bilddimensionen mit recht hoher (100%) Wahrscheinlichkeit alles über den
Inhalt des Arrays, was man wissen muß, um es korrekt darstellen zu
können. Sofern es überhaupt einen sinnvollen Inhalt hat, natürlich
nur...
> Mir ist klar, dass ich dies irgendwie mit 2 For-Schleifen realisieren> muss, aber ich bekomme es nicht hin.
Erst muß dir der Aufbau deiner Daten klar sein, DANN kannst du einen
Algorithmus finden, um sie sinnvoll an das Display zu verfüttern. Nur so
herum funktioniert das. Aber ja, i.d.R. werden zwei Schleifen nötig
sein...
Hi
>Zur Verfügung stehen mir eine>// Set page address 0~15>void Set_Page_Address(unsigned char add)>void Set_Column_Address(unsigned char add)>und eine Funktion, die die 8 Bit ans Display sendet>void Write_Data(unsigned char dat)
Die Funktion Set_Page suggeriert das 8 untereinander liegende Bits in
einem Byte enthalten und ausgegeben werden. In der Beschreibung des
Grafikonverters (allerdings nur schnell überlesen) finde ich aber
folgende Aussage:
Raster Data Encoding for 1bit/black & white images
Every byte holds 8 pixels, its LSB representing the leftmost pixel.
There are 2 color table entries.
Bedeutet für mich, das die Daten des Konverters nicht zum Display
passen. Evtl. reicht es das Bitmap um 90° zu drehen.
MfG Spess
... hm, meine "Lösung" ist rudimentärer Art, weil sie eine Funktion
putpixel(uint8_t x, uint8_t y, uint8_t f);
benötigt. Ich habe zwar auch schon eine "showimage" gemacht, die 8 Pixel
direkt in ein Display schreiben, aber das hängt dann schon sehr vom
Dispaly
ab (bei mir waren das die Nokia Displays 3410, 3310, 5110).
Seh dir die Anleitung im Anhang an und vllt. bastelst dir eine putpixel
Funktion um dann das ganze für dein Display so zu realisieren, dass ein
Zugriff gleich 8 Pixel schreibt.
Viel Spaß damit !
Ralph
----------------------------------------------
PS: sorry, aber die Datei "girlie.bmp" lässt sich nicht als *.bmp Datei
anhängen, microcontrollernet scheint die automatisch in eine PNG Datei
zu konvertieren. Der Konverter funktioniert aber nur mit einer BMP
Datei. Deshalb:
eigenes SW-BMP Bild nehmen !
----------------------------------------------
Danke schon mal für alle Antworten.
Ich versuche jetzt das angehängte 240x120 Pixel Bild auf dem Display
auszugeben.
Das Bild hat 3600 (225x16) Einträge und sind in dem folgenden Array
durch den Microchip Konverter abgelegt:
Ich verstehe immer noch nicht genau wie der Converter die Daten
konvertiert, d.h. die Reihenfolge ist das Problem.
Ihr werdet es nicht glauben, aber die Anzeige bzw. Verschachtelung in
zwei For Schleifen kriege ich hin :)
Das Verständnis fehlt mir zugegebener maßen.
Simon schrieb:> Ich verstehe immer noch nicht genau wie der Converter die Daten> konvertiert, d.h. die Reihenfolge ist das Problem.
Das lässt sich aber recht leicht rauskriegen, wenn man erst mal seine
Hausaufgaben macht.
Mach dir eine Bitmap, in der du in der linken oberen Ecke genau 2 Pixel
auf schwarz setzt. Entweder direkt nebeneinander oder direkt
übereinander.
Und dann siehst du dir in den Daten an, wo die korrespondierenden 1-Bits
auftauchen. So viele Möglichkeiten gibt es da ja nicht bei lediglich 2
schwarzen Pixel.
Wenn man etwas nicht weiß, dann muss man sich eben überlegen, wie man
das mit geeigneten Testdaten rauskriegen kann. Da gleich mit dem
endgültigen 'komplexen' Bild anzufangen, ist meist erst mal ein Umweg,
weil man vor lauter Daten die Details nicht mehr sieht. Also wird
abgespeckt, bis man derart einfache Testdaten hat, dass man das gesuchte
Detail nicht mehr übersehen kann.
IMHO ist das einer der Karidnalfehler vieler Nachwuchs-SW-Entwickler:
sie gehen immer mit viel zu komplizierten Testfällen an eine Sache ran,
anstatt erst mal nach der Devise zu handeln 'so einfach wie nur
irgendwie möglich und so, dass ich das was ich nicht weiß in den Daten
sehen kann'. Gar nicht so selten ist der vermeintliche 'Umweg' über eine
vereinfachte Version auf lange Sicht der schnellere Weg.
Hi
Deine Datei sieht, etwas bearbeitet, wie im Anhang aus. Allerdings mit
LSB Left. Wenn dein Display eine senkrechte Bitanordnung hat,kommt dann
natürlich Mist heraus.
MfG Spess
spess53 schrieb:> Hi>>>Ich versuche jetzt das angehängte 240x120 Pixel Bild auf dem Display>>auszugeben.>> Und was zeigt das Display?>> MfG Spess
Das Display zeigt 8 aufeinander folgende "a"s an und schwarz <-> sind
dabei noch invertiert.
Ziel ist ja Pages 0..16 jeweils alle 240 Pixel auszugeben.
Die oben beschriebene Ausgabe ergibt sich mit:
1
voidDisplay_Picture(unsignedcharpic[])
2
{
3
unsignedchari,j,num=0;
4
for(i=0;i<15;i++)
5
{
6
Set_Page_Address(i);
7
Set_Column_Address(0x00);
8
for(j=0;j<240;j++)
9
{
10
Write_Data(pic[num*240+j]);
11
}
12
num++;
13
}
14
return;
15
}
Ich werde versuchen der Vorschlag von Herrn Brunegg zu beherzigen.
Simon schrieb:> Write_Data(pic[num*240+j]);
Die entscheidende Fragen sind:
* wie sind die Pixel in den Daten angeordnet:
nebeneinander oder übereinander.
Sprich: die 8 Bits eines Bytes entsprechen dieser Pixelanordnung
1
+---+---+---+---+---+---+---+---+
2
| | | | | | | | |
3
+---+---+---+---+---+---+---+---+
oder dieser Pixelanordnung
1
+---+
2
| |
3
+---+
4
| |
5
+---+
6
| |
7
+---+
8
| |
9
+---+
10
| |
11
+---+
12
| |
13
+---+
14
| |
15
+---+
16
| |
17
+---+
* wie will das Display die Daten haben
und wieder gibt es die beiden Möglichkeiten der prinzipiellen
Pixelanordnung.
Wenn klar ist, ob die 8 Bits eines Bytes als 'waagrechte' oder als
'senkrechte' Pixelanordnung anzusehen ist, bleibt noch die Frage: wo ist
das Bit 0 in den Pixeln? links oder rechts (oder oben bzw. unten im
senkrechten Fall)
Das muss man eben erst mal rauskriegen, wenn man keine Unterlagen hat.
Das lässt sich aber mit ein paar Testdaten schnell eruieren.
Edit: mir gehts jetzt nicht darum, dass ich rauskriege, wie sich das
verhält. Denn deine Beschreibungen zeigen schon, was da los ist. D.h.
wenn man ein derartiges 'Problem' schon mal gelöst hat. Mir geht es
darum, wie man prinzipiell an derartige Dinge rangeht. Denn in einem
Forum 'Hilfe' zu schreien, ist mir ehrlich gesagt zu billig. Von einem
SW_Entwickler erwarte ich mehr. Unter anderem auch, dass er sich selber
helfen kann und prinzipielle Problemlöse-Strategien anwenden und aus dem
was er sieht die richtigen Schlüsse ziehen kann.
OK,
danke nochmal für die ganzen Antworten.
Ich habe mir jetzt ausführlich das Datenblatt zu Controller (UC1608)
angeguckt.
Hier steht geschrieben, dass die Pixelanordnung des Displays für jede
Page als senkrecht anzuordnen sind. Da MSF = 0bedeutet dies, dass die
Bits senkrecht in der Reihenfolge D7 | D6 ... | D0 angeordnet sind,
wobei das erste Bit für die jeweilige Page "links unten" beginnt. Auszug
aus dem Datenblatt siehe Anhang.
Wie Spess freundlicherweise erläutert bzw. in der Datei gezeigt hat,
werden in dem Converter die Bytes jedoch in waagrechter Form abgelegt.
Ich muss jetzt
a) einen Converter suchen, der das Bild in das gewünschte Format
formatiert
oder
b) dieses in der Software abfangen.
Für b ist es vermutlich einfacher das Array entsprechend vorher zu
bearbeiten.
D.h. aus
Hi
>Ich muss jetzt>a) einen Converter suchen, der das Bild in das gewünschte Format>formatiert>oder>b) dieses in der Software abfangen.
Oder
c) Dreh das Bitmap um 90° -> 120x240 Pixel
MfG Spess
spess53 schrieb:> c) Dreh das Bitmap um 90° -> 120x240 Pixel
Richtig. Und zwar bevor du es an den Konverter verfütterst.
Gibt es zu diesem ominösen Mikrochip Konverter eigentlich keine
Dokumentation? Die sollte 99,9% der anfänglich fraglichen Punkte aus dem
Stehgreif beantworten konnen.
Nur lesen muß man sie dann noch...
spess53 schrieb:> gibt es. Daher stammt doch das hier>> Raster Data Encoding for 1bit/black & white images>> Every byte holds 8 pixels, its LSB representing the leftmost pixel.> There are 2 color table entries.
Also dieser Auszug klärt die Sache noch nicht wirklich erschöpfend.
Geklärt ist damit Bitorder (LSB first) und Byteorder (irrelevant->in
order of appearance). Nicht geklärt ist ein eventueller pitch/stride.
Allerdings: wenn sowas nirgendwie sonst in der Doku erwähnt wird, dann
kann man vielleicht davon ausgehen, daß es sowas auch nicht gibt.
Es würde allerdings alles extrem ineffizient machen, wenn die Bildbreite
nicht durch 8 teilbar ist, eine Zeile also nicht in eine ganzzahlige
Zahl von Bytes (für C-Fetischisten: chars) paßt.
Und weil das so ist, wage ich zu behaupten, daß nichtmal Microchip so
doof war, es tatsächlich so zu machen. Ob ich Recht habe, wird sich
zeigen, wenn der OP versucht, sein ursprüngliches Bild anzuzeigen. Da
ist nämlich weder Höhe noch Breite durch 8 teilbar, d.h.: auch eine
vorherige Rotation wird hier nicht weiterhelfen...
Ich bin schon ganz gespannt auf die neueste Inkarnation von völlig
stupiden C-Routinen zur Bildverarbeitung. Nicht, daß ich nicht schon
wirklich jeden Scheiß gesehen hätte, der diesbezüglich überhaupt denkbar
ist... ;o)
Hi
>Es würde allerdings alles extrem ineffizient machen, wenn die Bildbreite>nicht durch 8 teilbar ist, eine Zeile also nicht in eine ganzzahlige>Zahl von Bytes (für C-Fetischisten: chars) paßt.
Dafür gibt es Padding-Bits. Braucht der TO aber nicht. Wenn ich das
richtig sehe hat er 240 Pixel pro Zeile und 16 Pages a 8Bit, also 128
Bit, Höhe. Der Grafik-Konverter behandelt allerdings monochrome Displays
recht stiefmütterlich.
MfG Spess
spess53 schrieb:> Bit, Höhe. Der Grafik-Konverter behandelt allerdings monochrome Displays> recht stiefmütterlich.
Der behandelt eigentlich recht viel ziemlich stiefmütterlich. Gerade bei
so einem Konverter ist es doch nicht so abwegig, dass man die
Pixelausrichtung des zu erzeugenden Codes angeben sollte, egal ob
monochrom oder in Farbe.
Berühmt ist das nicht, was man da an Konfigurationsmöglichkeiten hat.
(Ich nenn das gerne 'amerikanisch'. Hauptsache es sieht aus der Ferne
gut aus, genauer nachsehen darf man nicht)
Ich starte noch einmal einen aller letzten Versuch und starte noch
einmal mit der Funktion die das BMP auf dem Display ausgeben soll.
1
voidDisplay_Picture(unsignedcharpic[])
2
{
3
unsignedchari,j,num=0;
4
for(i=0;i<15;i++)
5
{
6
Set_Page_Address(i);
7
Set_Column_Address(0x00);
8
for(j=0;j<240;j++)
9
{
10
Write_Data(pic[num*240+j]);
11
}
12
num++;
13
}
14
return;
15
}
Das auszugebene Array hat 240 x 120 bzw. 120 x 240 Bit, also 3600 Byte.
Die Display Picture Funktion habe ich beim debuggen untersucht und Sie
macht genau das was ich eigentlich auch vermute.
Sie geht für jede Page (0..15) die 240 Pixel durch und zeichnet die
Pixel in "senkrechter Anordnung". Soweit so gut eigentlich. Trotzdem
kommt nur Unfug heraus.
Das beste Ergebnis habe ich bei dem oben abgebildeten "a-Symbol" Dort
bekomme ich das Symbol zumindest verzerrt und 8 mal (bzw. 16mal)
angezeigt. Zusätzlich noch invertiert. Aber dies lässt sich ja schnell
abfangen.
Irgendwas läuft also vermutlich noch bei der Konvertierung falsch.
Ich nehme mir eine BMP Datei und schneide Sie auf die Größe 240x120 bzw.
120x240 Pixel zu Recht und speichere diese als Monochrom BMP ab (1-Bit
Farbtiefe) und jage diese dann durch den Konverter.
Das Array binde ich dann natürlich in meinem Projekt ein und rufe dieses
mit der DisplayPicture Funktion auf!
HI
>Irgendwas läuft also vermutlich noch bei der Konvertierung falsch.>Ich nehme mir eine BMP Datei und schneide Sie auf die Größe 240x120 bzw.>120x240 Pixel zu Recht und speichere diese als Monochrom BMP ab (1-Bit>Farbtiefe) und jage diese dann durch den Konverter.
Dein Konverter macht schon das richtige. Aber bei einem 90° gedrehtem
Bild stimmt deine 'Display_Picture' in der Form nicht.
Aber vergiss den Konverter trotzdem mal und versuch mal dieses Tool
Beitrag "Grafikkonverter Tool für AVR/Mikrocontroller (BMP2C, BMP2ASM, BMP2BASCOM)"
MfG Spess
spess53 schrieb:> Dein Konverter macht schon das richtige. Aber bei einem 90° gedrehtem> Bild stimmt deine 'Display_Picture' in der Form nicht.
Drehen ist, denke ich, auch die falsche Operation.
Um dieser Ausgabroutine zuzuarbeiten, müsste man das Bild an der
Diagonalen spiegeln. Und natürlich darauf achten, dass danach Bildhöhe
und Bilbreite in Bytes wieder richtig sind.
(Da hätt ich mir schon längst auf dem PC ein Programm geschrieben,
welches genau diese Operation auf den Daten macht. Und sei es auf dem
vom Konverter generierten Datenfeld)
Danke,
sehr schönes TOOL. Gefällt mir eindeutig besser als der Microchip
Converter, bringt leider keinerlei Verbesserung.
Vielleicht könnte es auch mit der Init (ich habe die im angegebenen Link
genutzt:
http://www.buydisplay.com/download/democode/ERC240120-1_DemoCode.txt)
Dort wird einmal das LCD Mapping Control über
1
Write_Instruction(0b11000100);//set LCD mapping control MX=1,MY=0
eingestellt.
Dort heisst es wie im Bild im Anhang aus dem Datasheet des
Displaycontrollers. Dort habe ich auch schon vieles ohne Erfolg
ausprobiert.
Die komplette Init sieht wie folgt aus:
1
Write_Instruction(0xE2);//system reset
2
// Delay(200);
3
waitlcd(2000);
4
Write_Instruction(0x27);// Multiples rate :128 set temperature consenpation
5
6
// Write_Instruction(0xC4);//set LCD mapping control MX=1,MY=0
7
Write_Instruction(0b11000100);//set LCD mapping control MX=1,MY=0
8
9
Write_Instruction(0xEA);//set bias:1/12bias
10
11
12
Write_Instruction(0x81);//Set Gain and Potentiometer
13
Write_Instruction(0x40|Contrast_level);//Set Gain and Potentiometer xx xxxxxx
14
15
Write_Instruction(0x2f);//Power Control:internal
16
Write_Instruction(0x40);//Set Start Line -> Start Line 0
Simon schrieb:>> Vielleicht könnte es auch mit der Init (ich habe die im angegebenen Link> genutzt:> http://www.buydisplay.com/download/democode/ERC240120-1_DemoCode.txt)
gehen wir mal davon aus, dass es die Init nicht ist.
> sehr schönes TOOL. Gefällt mir eindeutig besser als der Microchip> Converter, bringt leider keinerlei Verbesserung.
Und schon wieder der gleiche Fehler: gleich in die vollen gehen.
hast du dir denn die erzeugten Daten mal angesehen? Und zwar nicht mit
einem komplexen Bild, sondern mit ganz banal 2 schwarzen Pixel in der
linken oberen Ecke?
Man könnte auch mal mit kleineren Bildern hantieren, dann hat man nicht
so einen Datenwust. Ein 8 mal 16 Pixel Bild, wie zb das hier
1
unsignedcharimageData[]={
2
0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// Pixelzeilen 0 bis 7
3
0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// Pixelzeilen 8 bis 15
einen senkrechten Balken am linken Bildrand erzeugen.
(Und natürlich nur ein 8 * 16 Bild anzeigen, d.h. rund um das Bild kann
es natürlich zu Artefakten kommen. Dieser Bereich ist ja nicht Teil des
Bildes und wird auch nicht beeinflusst.
Dann weisst du erst mal, dass deine Init funktioniert und das dein
Display_Picture soweit funktioniert.
(Das Problem ist, dass dein Konverter ein entsprechendes BMP eben nicht
so wie oben als Datenfeld erzeugt, sondern er die Pixel nebeneinander in
jeweils 1 Byte anordnet.
der würde also für genau dasselbe Bild das hier erzeugen
1
0x01,// Pixelzeile 0
2
0x01,// Pixelzeile 1
3
0x01,// Pixelzeile 2
4
0x01,// ....
5
0x01,
6
0x01,
7
0x01,
8
0x01,
9
0x01,
10
0x01,
11
0x01,
12
0x01,
13
0x01,
14
0x01,
15
0x01,
16
0x01,
und das ist offensichtlich etwas ganz anders.
Man kann das natürlich in der Display_Picture alles berücksichtigen und
sich zur Ausgabe die Bits entsprechend zusammenholen. Aber eigentlich
ist es unsinnig, das jedesmal im Controller-Programm zu machen, wenn man
auch im Vorfeld das Datenarray schon korrekt bereit stellen kann. Und
sei es nur dadurch, dass man das vom Konverter erzeugte Ergebnis noch
mal durch ein C-Programm jagt, welches die Spiegelung macht und ein
neues Datenarray ausgibt.
)
Ich kann es nicht oft genug betonen:
Wenn man einen Prozess zum laufen bringen will, dann fängt man erst mal
mit einfachen, kleinen Datensätzen an! Bei Bildern sind das dann eben
nicht die 4096*8192 Pixel Bilder (womöglich noch in RGBA) sondern erst
mal kleine Bilder mit wenigen Pixeln (und womöglich einer Bildgröße, die
eine 2-er Potenz darstellt). Dann kann man auch zur Not sich selber mal
die Daten ansehen und dann sieht man auch etwas, was man als Mensch noch
recht problemlos interpretieren kann (und sei es mit Papier und
Bleistift) und nicht nur 5 Bildschirmseiten mit Hex-Zahlen!
Ihr macht euch nur selbst das Leben schwer, wenn ihr immer gleich 'in
die Vollen' geht! Erst mal muss es mit einfachen, kleinen Daten
funktionieren. Dann erst wird gesteigert. Das ist hier auch nicht anders
wie in der Software-Entwicklung an sich. Auch dort ist es Unfug 8 Seiten
ungetesteten Code hinzuschreiben in der Hoffnung, das wird schon
funktionieren.
Das Um und Auf in der kompletten Informatik ist es klein anzufangen und
dort aus Fehlern und Problemen seine Schlüsse zu ziehen.
Karl Heinz schrieb:> einen senkrechten Balken am linken Bildrand erzeugen.
Durch Modifikation der Daten, zb
1
unsignedcharimageData[]={
2
0xFD,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// Pixelzeilen 0 bis 7
3
0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// Pixelzeilen 8 bis 15
4
};
bzw
1
unsignedcharimageData[]={
2
0xBF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// Pixelzeilen 0 bis 7
3
0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// Pixelzeilen 8 bis 15
4
};
kannst du dich auch davon überzeugen, dass die Zuordnung der Bits zu den
Pixeln genau so ist, wie erwartet. 0xFD ist binär 11111101, d.h da muss
eine Lücke in der senkrechten auftauchen. Und da das niedrigste Bit dem
obersten Pixel entspricht, muss die Lücke am oberen Ende des senkrechten
Strichs sein.
Wohingegen 0xBF binär 10111111 entspricht. D.h. die Lücke muss deutlich
weiter 'unten' in der senkrechten Linie auftauchen.
Wenn das am Display wie erwartet aussieht, ist auch geklärt ob der Modus
richtig eingestellt ist.
Hallo Herr Buchegg,
erst einmal vielen Dank für den ganzen Input. Ich verstehe auch Ihr
Anliegen einen grundsätzlichen Lernweg für Software-Laien zu vermitteln
und werde gerade in Zukunft versuchen dies zu beherzigen.
Auch wenn die richtige Darstellung immer noch nicht funktioniert habe
ich trotzdem etwas über Displays, Bitmap Format etc. gelernt.
Wie das Display vorgeht, in welcher Reihenfolge die Pixel geschrieben
werden etc. ist mir auch soweit klargeworden.
Das von Ihnen erläuterte Minimalbeispiel funktioniert wie von Ihnen
erwartet (weißer Balken weit oben und weißer Balken weit unten).
Der Modus sollte also richtig eingestellt sein.
Mein grundsätzliches Problem ist also immer noch dass die Daten
scheinbar im falschen Format vorliegen.
In der DisplayPicture Funktion habe ich keinen Ansatz wie man das
realisieren könnte.
Bleibt also nur noch ein C-Tool zu schreiben, welches genau diese
Konvertierung vornimmt, also eine Spiegelung des Arrays an der
Diagonalen. Das bedeutet aus einem Array mit m- Spalten und n-Zeilen
wird ein Array mit n-Spalten und m-Zeilen. Perfekt wäre wenn man dieses
dann in der DisplayPicture integrieren könnte!
Leuchtfeuer schrieb:> Das von Ihnen erläuterte Minimalbeispiel funktioniert wie von Ihnen> erwartet (weißer Balken weit oben und weißer Balken weit unten).>> Der Modus sollte also richtig eingestellt sein.
Gut Das ist ja schon mal was.
> Mein grundsätzliches Problem ist also immer noch dass die Daten> scheinbar im falschen Format vorliegen.
:-)
Nicht nur scheinbar. Das ist tatsächlich so.
> In der DisplayPicture Funktion habe ich keinen Ansatz wie man das> realisieren könnte.
Na ja. Möglich ist es natürlich schon. Denn es sind ja prinzipiell
dieselben Pixel.
Um also der Zeichenfunktion, die 8 senkrechte Pixel hinmalen will, das
richtige Byte zu übergeben, müsste man sich eben die 8 entsprechenden
Bits aus den richtigen Bytes des Datenfeldes rausholen. Es ist ja
schliesslich bekannt, wie hier der Zusammenhang sein muss, weil ja die
Ausrichtung bekannt ist. Und der Rest ist dann im Grunde nichts anderes
als Bitmanipulation, wie sie jeder µC-Programmierer beherrscht.
um der Zeichenfunktion die 8 Bits für diese Spalte
1
0 1
2
3
+-+ +-+ ...
4
7 | | | |
5
+-+ +-+
6
6 | | | |
7
+-+ +-+
8
5 | | | |
9
+-+ +-+
10
4 | | | |
11
+-+ +-+
12
3 | | | |
13
+-+ +-+
14
2 | | | |
15
+-+ +-+
16
1 | | | |
17
+-+ +-+
18
0 | | | |
19
+-+ +-+
20
21
+-+ +-+ ....
22
| | | |
23
+-+ +-+
24
| | | |
25
.
26
.
27
.
anzubieten, muss man eben genau diese 8 Bits aus den zeilenweise
vorliegenden Daten
(die beiden Grafiken muss man sich übereinandergelegt vorstellen, ist
mit ASCII schlecht zu zeichnen. Jedes Kästchen stellt 1 Pixel dar. Nur
das eine mal ist dieses Pixel in ein System eingebettet, in dem jeweils
8 senkrecht übereinander liegende Bits 1 Byte bilden und das andere mal
sind jeweils 8 nebeneinander liegende Bits zu einem Byte
zusammengefasst).
D.h. in der Version mit den senkrechten Pixeln kommt der Wert (0 der 1)
für das Bit 7 aus dem Byte 0 der waagrechten Version und ist dort das
Bit 7.
Das in der senkrechten Version unmittelbar darunter liegende Bit 6
stammt in der waagrechten Version aus dem Byte 2 und ist dort ebenfalls
das Bit 7. Für das senkrecht Bit 5 wird das Bit 7 aus dem Byte 4
herangezogen. usw.
Alle diese Eizelbits werden temporär zu einem Byte zusammengesetzt, so
dass dieses Byte genau dieselben 0 und 1 aufweist, wie es die horizontal
angeordneten Bytes an genau diesen Pixelpositionen hatten und dieses
Senkrecht-Byte an die Ausgabefunktion übergeben.
Damit ist das erste Senkrecht Byte ausgegeben. Wie muss das Senkrecht
Byte aussehen, welches gleich danach für die Spalte 1 ausgegeben wird.
Nun: sein Bit 7 kommt aus dem horizontal Byte 0, aber diesmal ist es
dort das Bit 6. Das Senkrecht Bit 6 kommt aus dem Horizontal Byte 2 und
ist dort ebenfalls das Bit 6. Das senkrechte Bit 5 kommt aus dem Byte 4
und ist dort wieder das Bit 6. usw. usw.
> wird ein Array mit n-Spalten und m-Zeilen. Perfekt wäre wenn man dieses> dann in der DisplayPicture integrieren könnte!
Eher nicht, denn das Zusammensuchen der Bytes ist relativ aufwändig. Man
kann es natürlich zum Testen da mal einbauen, aber im Endeffekt ist es
recht unsinnig, diese Bitzusammensucherei jedesmal neu zu machen, wenn
das Bild ausgegeben werden soll.