Go Down

Topic: Problem converting BMP into correct OLED image. (SOLVED) (Read 6238 times) previous topic - next topic

Nick Gammon

Code: [Select]
  Set_Row_Address(0x00,0x7F);

Where's the datasheet? Why don't you start at row 0?

Quote
Binary sketch size: 11134 bytes (of a 30720 byte maximum)
avrdude: verification error, first mismatch at byte 0x00bd
         0xff != 0xfe
avrdude: verification error; content mismatch


There a bug in the bootloader where trailing 0xFF are not written. Try to put some other byte (eg. 0x01) as the last data byte in the sketch.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

SVFeingold

The datasheet is linked in the first post. Here it is again: http://www.newhavendisplay.com/app_notes/SSD1322.pdf

Here are the row and column functions:
Code: [Select]
void Set_Column_Address(unsigned char a, unsigned char b)
{
oled_Command(0x15); // Set Column Address
oled_Data(a); //   Default => 0x00
oled_Data(b); //   Default => 0x77
}

//--------------------------------------------------------------------------

void Set_Row_Address(unsigned char a, unsigned char b)
{
oled_Command(0x75); // Set Row Address
oled_Data(a); //   Default => 0x00
oled_Data(b); //   Default => 0x7F
}


And then the command and data functions:
Code: [Select]
//--------------------------------------------------------------------------
//send Command to OLED
//--------------------------------------------------------------------------
void oled_Command(unsigned char Data)
{
 
unsigned char i;  //begin 4-wire serial mode
 digitalWrite(displayDC,LOW);
 digitalWrite(displaySelect,LOW);
 SPI.transfer(Data);
 digitalWrite(displayDC,HIGH);
 digitalWrite(displaySelect,HIGH);
}

//--------------------------------------------------------------------------
//send Data to OLED
//--------------------------------------------------------------------------
void oled_Data(unsigned char Data)
{
unsigned char i;
 digitalWrite(displayDC,HIGH);
 digitalWrite(displaySelect,LOW);

 SPI.transfer(Data);
 
 digitalWrite(displaySelect,HIGH);
}


When using the row and column address functions, the first byte sent is the command byte. So when calling Set_Row_Address(A,B), A is the first address and B is the last address, and it writes to all addresses between the two.

The addresses corresponding to this display are column: 0x1C to 0x5B (28 - 91; 256 pixels with 4 pixels/column) and the row addresses are 0x00 to 0x3F (0 to 63; 64 pixels for the display height).

Does the bootloader error affect the performance of the program? If I leave the void loop() section blank, the last byte sent should be a 0x01, as that is the last byte in the image array and the last function performed in void setup() is to write the image and de-select the display. I still get the same error though:
Code: [Select]
Binary sketch size: 11036 bytes (of a 30720 byte maximum)
avrdude: verification error, first mismatch at byte 0x00bd
        0xff != 0xfe
avrdude: verification error; content mismatch


Last part of my image array:
Code: [Select]
.......0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x01
);


SVFeingold

#17
Apr 13, 2012, 01:05 am Last Edit: Apr 13, 2012, 01:08 am by SVFeingold Reason: 1
I should also add that I've tried using this code in "void loop()"
Code: [Select]

void loop(){

   if (digitalRead(button)){
       clear_Screen();
   }
}


So once the image is loaded (Same as the most recent image I posted with the two lines of text), pressing a button attached to a digital input runs the clear screen function. This function has been modified to only address the parts of the display RAM corresponding to this specific screen. Otherwise it takes much longer to clear the screen, but I also wanted to test if there was some error in my loop that iterates through each element of the image array.

Here is the modified clear_Screen():
Code: [Select]
void clear_Screen()
{
 Set_Column_Address(0x1C,0x5B);
 Set_Row_Address(0x00,0x3F);
 Set_Write_RAM();
 digitalWrite(displaySelect,LOW);
 digitalWrite(displayDC,HIGH);
 for(unsigned int i=0; i<8192; i++){
   SPI.transfer(0x00);
 }
 digitalWrite(displaySelect,HIGH);
}


After loading the code with this change, pushing the button does indeed clear the screen completely. All pixels are completely off. Resetting the Arduino reloads the same (faulty) image.

So this leads me to believe that the process of writing to the display is working as it should. I am now starting to suspect that the problem is on the Arduino end, but I don't know enough about how FLASH memory is written/read on the Arduino to know if that is the culprit.

I've also checked the array and there are exactly 8192 bytes there, as it should be.

Nick Gammon

Sounds a bit like when you load a small image you aren't putting it all into memory, so when you copy it to the OLED you are copying part of the earlier image.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

SVFeingold

When it's a small image though, nothing else shows except the image as it is supposed to look. It's only when I load a full size image.

I am having a difficult time understanding by what mechanism it is happening. For instance with the image I posted of the two lines of text. There is no compression happening, the program should be "dumb" and just copy every byte of image data as it is in the array. Why would only the text show up correctly but not the parts above/below the text?

It looks like rows with all "0xFF" data are just being skipped entirely, but why? If I invert the image and make another array, it shows up correctly. I can then send the display an "invert" command to get it back to how it is supposed to look, and I suppose I can work with that behavior although I don't like to without understanding what is really going on. Is it an issue with the display or with the Arduino?

SVFeingold

I can confirm that the faulty data is being sent over the SPI bus (tested with logic analyzer), so I don't think the display is at fault. I'm directly comparing the first bytes of the image array with the first bytes being sent to the display after the proper commands (also verified).

Here is the current image:


As it shows up:


First bit of the image array:
Code: [Select]
FLASH_ARRAY(unsigned char, test,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
....


And part of the SPI data stream:
http://i.imgur.com/1ICCm.jpg

The first bytes on the left are the row and column address commands being sent, followed by a command to enable writing to the RAM. Between the markers are roughly 280 bytes, corresponding to about 565 pixels (just over 2 rows). The first couple dozen bytes of 0xFF followed by a couple hundred bytes of 0x00 matches exactly what is seen on the screen. So the display itself seems to be working as it should, but the data being sent is faulty. If you look at the array, you see it is all 0xFF for a good while at the start.

After this I am confident that something is going on inside the Arduino that I am not understanding.

Nick Gammon

What is that screen shot proving? I see some zeroes in your data, and zeroes in the logic analyzer. Can you narrow down the part you think is wrong?

Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

SVFeingold

#22
Apr 14, 2012, 02:43 am Last Edit: Apr 14, 2012, 02:44 am by SVFeingold Reason: 1
In the array, the first zero is the 302nd byte, before that is all 0xFF. This corresponds to the 604th pixel, which would be about 35% of the way into the third row - the display is scanned horizontally. If you look at the original image file, that is exactly where the first zero is. So the image array is correct in that regard. I should clarify since it may be hard to see; the first part of the text encountered while scanning the display (horizontally, left to right; vertically, top to bottom) is the top of the 'S.' The uppermost part of the 'S' is on the third row of pixels.

However the display is clearly not showing that, it is showing a short line of 0xFF followed by a bunch of zeros on the first, second, and part of the third row. The SPI stream shows that this is indeed what is being sent to the display. So the display is faithfully displaying the data being sent to it, but the data is incorrect. The data sent SHOULD match the image array exactly, and the image array is correct. So, somewhere between writing the data to the flash memory upon uploading the sketch, and reading the data from the array and sending it over the bus, the data is being corrupted.

To me this is very strange, I see no logical reason from my code why this should happen. Unless the Arduino itself is faulty, or the Flash library I used is faulty (http://arduiniana.org/libraries/flash/), I see no logical reason why this should be happening.

Nick Gammon

Well to comment further I would have to see the code and preferably reproduce it. Can you make a minimal example that compiles, with the problem data, and exhibits the problem? Then I can see whether or not it happens to me, and this rules in or out faulty hardware.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Go Up