thomas 发表于 2012-3-11 14:22:21

Arduino驱动OLED显示屏试验

本帖最后由 thomas 于 2012-3-11 16:45 编辑

Arduino入手快一个月了,总想尝试做点儿什么。距离我上一次接触单片机已经是15年前了,不知怎么就鬼使神差的买了Arduino开发板。以前我用的是更简单的PIC58,用BASIC编程的机器,非常好用,后来没有卖了。
言归正传,雪季快结束了,我想做个显示时速、海拔、坡度的滑雪镜。于是,把目光放在了OLED显示屏上。这东西小巧,华丽,耗电低,同时低温性能非常出色。淘宝败了几个,主要是用96*16的微型显示屏。同时也败了个大点儿的128*64屏,双色的(分两色显示,不是真正的双色概念)非常便宜,96*16的15米一块,128*64的驱动板才32米。

板子的到手,先拿大的试验。焊接好排针,接上电,按照普通12864的接法接上了。然后满怀期待的刷入测试程序。。。屏幕一片黑。Arduino板子的led灯全黑,计算机提示未知硬件。木瓜一样发了10秒呆,然后闻到一股久违的糊味。。。果断拔电,板子已经发烫了。
(待续)
很明显接近短路状态,用表一量,也没短路。
莫非是我焊针时焊坏了?可是我很谨慎啊,或者买来就是坏的?幸好买了两块,另一块先不焊,直接接电看看。
Arduino板子又黑了,还是短路现象,立即断电。
反复查看资料,发现一行红字。
----------------------------------------------------
MCU Bus Interface Pin Selection
Pin Name
I2C
Interface
6800-parallel
interface (8 bit)
8080-parallel
4-wire Serial
interface
3-wire Serial
interface
BS0 0 0 0 0 1
BS1 1 0 1 0 0
BS2 0 1 1 0 0
Note
(1) 0 is connected to VSS
(2) 1 is connected to VDD
interface(8 bit)
(3) Default interface is 80 80-parallel.(4) Please tell us the specific requirement of your company,we will provide appropriate interface to you.
----------------------------------------------------
数据模式分4种,用3组跳线选取,默认是80 80-parallel。
我小心翼翼的把贴片跳线改动了一下,把默认的011改成了000。
可,这绝不可能是短路的原因啊?我拿着板子仔细琢磨,发现了惊人的问题。
按照常识,电路板大面积覆铜的应该为GND,而按照资料显示,VSS的是PIN1,VDD是PIN2。不会是出厂图纸有问题吧,反正烧就烧把,我把电源极性换了一下,漂亮的图案出现了~
原厂资料有错误,标错了引脚极性,注意!!!





















zhd1021 发表于 2012-3-11 14:36:57

上个代码呗

taotao71 发表于 2012-3-11 15:02:44

这个比1602真的是强呀!!

Malc 发表于 2012-3-11 15:52:46

我想做个显示时速、海拔、坡度的滑雪镜
难道你要把他装在镜片上?

thomas 发表于 2012-3-11 16:04:41

本帖最后由 thomas 于 2015-2-2 23:37 编辑

编辑帖子老出错。先说接线图。
由于OLED多工作于3.3v,因此为了匹配输入端电压,用了一块缓冲器CD4050.
介绍
CD4050是非反相六缓冲器,具有仅用一电源电压(VCC)进行逻辑电平转换的特征。用作逻辑电平转换时,输入高电平电压(VIH)超过电源电压VCC。该器件主要用作COS/MOS到DTL/TTL的转换器,能直接驱动两个DTL/TTL负载。16引出端是空脚 ,与内部电路无连接。

接线

Arduino IO端口         CD4050引脚
DIGITAL
9    ----------------------   14
10----------------------   11
11----------------------   9
12----------------------   5
13----------------------   3
+5v   ------------------1
GND   -------------------8



LM096-128064引脚/ 功能      CD4050引脚
1------VDD---------------------------   1
2------VSS----------------------------   8
3 ------- CS# --------------------------4
4 --------RES# -----------------------   2
5 --------D/C#------------------------10
8--------- D0   -----------------------   12
9 -------- D1 --------------------------15


代码
#define OLED_DC 11
#define OLED_CS 12
#define OLED_CLK 10
#define OLED_MOSI 9
#define OLED_RESET 13

#include <SSD1306.h>

SSD1306 oled(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2


#define LOGO16_GLCD_HEIGHT 16
#define LOGO16_GLCD_WIDTH16
static unsigned char __attribute__ ((progmem)) logo16_glcd_bmp[]={
0x30, 0xf0, 0xf0, 0xf0, 0xf0, 0x30, 0xf8, 0xbe, 0x9f, 0xff, 0xf8, 0xc0, 0xc0, 0xc0, 0x80, 0x00,
0x20, 0x3c, 0x3f, 0x3f, 0x1f, 0x19, 0x1f, 0x7b, 0xfb, 0xfe, 0xfe, 0x07, 0x07, 0x07, 0x03, 0x00, };


void setup()   {               
Serial.begin(9600);

// If you want to provide external 7-9V VCC, uncomment next line and comment the one after
//oled.ssd1306_init(SSD1306_EXTERNALVCC);

// by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
oled.ssd1306_init(SSD1306_SWITCHCAPVCC);

// init done

oled.display(); // show splashscreen
delay(2000);
oled.clear();   // clears the screen and buffer

// Fill screen
oled.fillrect(0, 0, SSD1306_LCDWIDTH-1, SSD1306_LCDHEIGHT-1, WHITE);
oled.display();
delay(2000);

// draw a single pixel
oled.setpixel(10, 10, WHITE);
oled.display();
delay(2000);
oled.clear();

// draw many lines
testdrawline();
oled.display();
delay(2000);
oled.clear();

// draw rectangles
testdrawrect();
oled.display();
delay(2000);
oled.clear();

// draw multiple rectangles
testfillrect();
oled.display();
delay(2000);
oled.clear();

// draw mulitple circles
testdrawcircle();
oled.display();
delay(2000);
oled.clear();

// draw a white circle, 10 pixel radius, at location (32,32)
oled.fillcircle(32, 32, 10, WHITE);
oled.display();
delay(2000);
oled.clear();

// draw the first ~12 characters in the font
testdrawchar();
oled.display();
delay(2000);
oled.clear();

// draw a string at location (0,0)
oled.drawstring(0, 0, "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation");
oled.display();
delay(2000);
oled.clear();

// miniature bitmap display
oled.drawbitmap(30, 16,logo16_glcd_bmp, 16, 16, 1);
oled.display();

// invert the display
oled.ssd1306_command(SSD1306_INVERTDISPLAY);
delay(1000);
oled.ssd1306_command(SSD1306_NORMALDISPLAY);
delay(1000);

// draw a bitmap icon and 'animate' movement
testdrawbitmap(logo16_glcd_bmp, LOGO16_GLCD_HEIGHT, LOGO16_GLCD_WIDTH);
}


void loop()                     
{
for (uint8_t i=0; i<SSD1306_LCDWIDTH; i++) {
    for (uint8_t j=0; j<SSD1306_LCDHEIGHT; j++) {
      oled.setpixel(i, j, WHITE);
      oled.display();
    }
}


}


void testdrawbitmap(const uint8_t *bitmap, uint8_t w, uint8_t h) {
uint8_t icons;
srandom(666);   // whatever seed

// initialize
for (uint8_t f=0; f< NUMFLAKES; f++) {
    icons = random() % SSD1306_LCDWIDTH;
    icons = 0;
    icons = random() % 5 + 1;
   
    Serial.print("x: ");
    Serial.print(icons, DEC);
    Serial.print(" y: ");
    Serial.print(icons, DEC);
    Serial.print(" dy: ");
    Serial.println(icons, DEC);
}

while (1) {
    // draw each icon
    for (uint8_t f=0; f< NUMFLAKES; f++) {
      oled.drawbitmap(icons, icons, logo16_glcd_bmp, w, h, WHITE);
    }
    oled.display();
    delay(200);
   
    // then erase it + move it
    for (uint8_t f=0; f< NUMFLAKES; f++) {
      oled.drawbitmap(icons, icons,logo16_glcd_bmp, w, h, BLACK);
      // move it
      icons += icons;
      // if its gone, reinit
      if (icons > SSD1306_LCDHEIGHT) {
        icons = random() % SSD1306_LCDWIDTH;
        icons = 0;
        icons = random() % 5 + 1;
      }
    }
}
}


void testdrawchar(void) {
for (uint8_t i=0; i < 168; i++) {
    oled.drawchar((i % 21) * 6, i/21, i);
}   
}

void testdrawcircle(void) {
for (uint8_t i=0; i<SSD1306_LCDHEIGHT; i+=2) {
    oled.drawcircle(63, 31, i, WHITE);
}
}

void testdrawrect(void) {
for (uint8_t i=0; i<SSD1306_LCDHEIGHT; i+=2) {
    oled.drawrect(i, i, SSD1306_LCDWIDTH-i, SSD1306_LCDHEIGHT-i, WHITE);
}
}

void testfillrect(void) {
for (uint8_t i=0; i<SSD1306_LCDHEIGHT; i++) {
      // alternate colors for moire effect
    oled.fillrect(i, i, SSD1306_LCDWIDTH-i, SSD1306_LCDHEIGHT-i, i%2);
}
}

void testdrawline() {
for (uint8_t i=0; i<SSD1306_LCDWIDTH; i+=4) {
    oled.drawline(0, 0, i, SSD1306_LCDHEIGHT-1, WHITE);
    oled.display();
}
for (uint8_t i=0; i<SSD1306_LCDHEIGHT; i+=4) {
    oled.drawline(0, 0, SSD1306_LCDWIDTH-1, i, WHITE);
    oled.display();
}

delay(1000);

for (uint8_t i=0; i<SSD1306_LCDWIDTH; i+=4) {
    oled.drawline(i, SSD1306_LCDHEIGHT-1, 0, 0, BLACK);
    oled.display();
}
for (uint8_t i=0; i<SSD1306_LCDHEIGHT; i+=4) {
    oled.drawline(SSD1306_LCDWIDTH - 1, i, 0, 0, BLACK);
    oled.display();
}
}

thomas 发表于 2012-3-11 16:22:10

视频演示
http://player.youku.com/player.php/sid/XMzY0MTA0ODEy/v.swf




处理图像的工具
http://en.radzio.dxp.pl/bitmap_converter/LCDAssistant.zip

thomas 发表于 2012-3-11 16:28:32

本帖最后由 thomas 于 2012-3-11 16:29 编辑

Malc 发表于 2012-3-11 15:52 static/image/common/back.gif
难道你要把他装在镜片上?

当然不是装这个:P
我要装的是 96*16,0.69寸大小
微型屏,初步计划以反相的形式投影显示在镜片上。这个屏不配电路,需要自己做一块。

taotao71 发表于 2012-3-11 16:34:52

请问,屏和转接电路板是分开买的还是,原来就是一起的,我也想搞一块,玩玩!

taotao71 发表于 2012-3-11 16:37:41

怎么看,怎么喜欢呀!没有想到,Arduino可以驱动OLED显示屏!

thomas 发表于 2012-3-11 16:43:49

本帖最后由 thomas 于 2012-3-11 16:44 编辑

这块128064是一体的,0.96寸,32米一块。
别的都是需要精细焊接的,15米一块,需要自己做板子焊接,不建议实验用。
我不喜欢普通LED屏,太粗糙了。
喜欢OLED和VFD屏,做设计特别有感觉。

Malc 发表于 2012-3-11 16:57:10

thomas 发表于 2012-3-11 16:28 static/image/common/back.gif
当然不是装这个
我要装的是 96*16,0.69寸大小
微型屏,初步计划以反相的形式投影显示在镜片上。这 ...

额。。从没试过
不过我觉得能在镜片上显示很酷啊~
赶紧做个出来看看呗~{:soso_e128:}

jackwan 发表于 2012-3-13 12:51:54

看到thomas用arduino驱动此OLED模块的效果,非常好。

呵呵,我是此OLED模块的厂家。资料中第1pin和第2pin的定义错误已修改。
如果有需要的朋友,可以直接在此购买:
http://item.taobao.com/item.htm?id=13651995352
谢谢!

黑马 发表于 2012-3-14 21:10:42

请教一下为啥不用I2C?是因为刷新速度有差异么?

thomas 发表于 2012-3-14 22:49:21

RE: Arduino驱动OLED显示屏试验

黑马 发表于 2012-3-14 21:10 static/image/common/back.gif
请教一下为啥不用I2C?是因为刷新速度有差异么?

4-wire Serial熟悉些。arduino刚上手,底子也不好,摸索着来的。我感兴趣的应用似乎都是别人没兴趣的,全是自己摸索或从外网搜资料

黑马 发表于 2012-3-20 17:14:02

请教一下,我用4线SPI连接到MEGA,你的库文件,发现刷新一次数据要220ms左右,怎么都觉得不应该这么慢啊……抓狂ing……:Q
页: [1] 2 3 4 5
查看完整版本: Arduino驱动OLED显示屏试验