最終更新:2010-02-04 (木) 09:16:51 (5189d)
Arduino/µOLED
4D SystemsのµOLEDシリーズをArduinoで動かすメモ
対象
- µOLED-96-G1 (96x64)
- µOLED-128-G1 (128x128)
- µOLED-160-G1 (160x128)
メモ
に置いてあるライブラリは呼び出している関数(printByte)が無くなっているので新しいArduino IDEでは使えない
注意点
- µOLED-96-G1をArduinoのTX,RXにつなぐときは間に100〜200Ωの抵抗を挟む必要がある(3.3VのTTLのため)
- RX,TX端子を使うもの全てに言えることなのですが、プログラムを書き込む際はuOLEDの電源を切っておく必要があります。
●初期化時のボーレート自動検出 初期化時にuOLEDにボーレートを自動検出させるために、ホストから'U"の1文字を送信する必要がありますが、送信のタイミングが早すぎると検出がうまくいきません。実際にいろいろ試してみたところ、uOLEDに電源を入れてから、800ms以上時間をおいてからでないと、自動検出がうまくいきませんでした。テスト用のプログラムではマージンをみて1秒経過してから'U'を送信するようにしています。 ●コマンド間のインターバル 描画に時間がかかるコマンドを送信した後は、続けてコマンドを送信してもコマンドが受け付けられないことがあります。例えば (B) "Set Background Color" コマンド は背景を塗りつぶすのに時間がかかるため、500ms程度時間をあけてからでないと次のコマンドが受け付けられません。1文字表示のコマンドなどは続けてコマンドを送信しても問題ありませんが、(t) "Place text Character(フォーマットなし)" コマンドで拡大倍率を大きくするとやはり描画に時間がかかるため、、次のコマンドを送信するまでに数10~数100ms程度、ディレイを入れなければならない場合があります。 ディレイ時間を入れたくない場合には、uOLEDからの応答をチェックしてNAKが返されたら、コマンドを再送するようにすればよいでしょう。
とりあえずµOLED-160-G1で動いたコード
- Arduino 0017
#include <SoftwareSerial.h> #define rxPin 2 #define txPin 3 #define OLED_RESETPIN 8 #define OLED_ACK 0x06 // Ok #define OLED_NAK 0x15 // Error SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin); void setup() { pinMode(rxPin, INPUT); pinMode(txPin, OUTPUT); pinMode(8, OUTPUT); // sets the digital pin as output Serial.begin(9600);//for debug mySerial.begin(100000);//115kだと処理落ちした uOELD_Reset();//reset //リセットしてから1000ms待つ(でないと何も起きない) delay(1000); writeSerial('U');//ボーレート自動検出 writeSerial('E');//画面クリア for(int i=0;i<100;i++){ OLED_DrawLine(i,1+i,i,10+i,63488); delay(1); } //init } void writeSerial(char data){ //debug print Serial.print("write: "); Serial.println(data); mySerial.print(data); //get response Serial.println((int)OLED_GetResponse()); } void loop() { //nothing to do } //reset void uOELD_Reset(){ digitalWrite(OLED_RESETPIN, LOW); delay(20); digitalWrite(OLED_RESETPIN, HIGH); delay(20); } char OLED_GetResponse() { byte incomingByte = OLED_ACK; // Read incoming byte incomingByte = mySerial.read(); return incomingByte; } void OLED_DrawLine(char x1, char y1, char x2, char y2, int color) { // Line drawing mySerial.print('L'); // Line 0x4C渡しても何も起きない mySerial.print(x1); // x1 mySerial.print(y1); // y1 mySerial.print(x2); // x2 mySerial.print(y2); // y2 // Color mySerial.print(color >> 8); // MSB mySerial.print(color & 0xFF); // LSB }
oled160drv.h
- まだ修正途中。
- Serial.printにしたときはコマンドをcharで渡さないとだめ?
- 変更点
- #include "WProgram.h"を追加
- printByteをSerial.printに置換
/******************************************************* uOLED-160-GMD1 Driver for Arduino Code: Oscar Gonzalez August 2007 www.bricogeek.com fixed for Arduino 0017 by tokkyo Feb 2010 *******************************************************/ #include "WProgram.h" //error: 'LOW' was not declared in this scopeとか出るので追加 #define OLED_BAUDRATE 9600//57600 #define OLED_RESETPIN 8 // PIN of reset #define OLED_INITDELAYMS 5000 // Initialisation routine #define OLED_DETECT_BAUDRATE 0x55 // Drawing routines #define OLED_CLEAR 0x45 #define OLED_BKGCOLOR 0x42 #define OLED_COPYPASTE 0x63 #define OLED_LINE 0x4C #define OLED_CIRCLE 0x43 #define OLED_CIRCLEFILL 0x69 #define OLED_PUTPIXEL 0x50 #define OLED_READPIXEL 0x52 #define OLED_RECTANGLE 0x72 #define OLED_PAINTAREA 0x70 // Text properties #define OLED_SETFONTSIZE 0x46 #define OLED_FONT5X7 0x01 #define OLED_FONT8X8 0x02 #define OLED_FONT8X12 0x03 #define OLED_TEXTFORMATED 0x54 // OLED Control #define OLED_COMMAND_CONTROL 0x59 #define OLED_COMMAND_DISPLAY 0x01 #define OLED_COMMAND_CONTRAST 0x02 #define OLED_COMMAND_POWER 0x03 #define OLED_ACK 0x06 // Ok #define OLED_NAK 0x15 // Error void OLED_ResetDisplay() { digitalWrite(OLED_RESETPIN, LOW); delay(20); digitalWrite(OLED_RESETPIN, HIGH); delay(20); } char OLED_GetResponse() { byte incomingByte = OLED_ACK; // Wait for data avaliable while (!Serial.available()) { delay(1); } // Read incoming byte incomingByte = Serial.read(); return incomingByte; } // Initialise OLED display. You must first activate a serial comunication! void OLED_Init() { // First reset display OLED_ResetDisplay(); delay(OLED_INITDELAYMS); // Wait for init // Autodetect baudrate Serial.print(OLED_DETECT_BAUDRATE); OLED_GetResponse(); } // Get 16bits value from RGB (0 to 63, 565 format) int GetRGB(int red, int green, int blue) { char text[255]; int outR = ((red * 31) / 255); int outG = ((green * 63) / 255); int outB = ((blue * 31) / 255); return (outR << 11) | (outG << 5) | outB; } void OLED_Clear() { Serial.print(OLED_CLEAR); // Pixel write delay(20); OLED_GetResponse(); } void OLED_PutPixel(char x, char y, int color) { // Putpixel Serial.print(OLED_PUTPIXEL); // Pixel write Serial.print(x); // x Serial.print(y); // Color Serial.print(color >> 8); // MSB Serial.print(color & 0xFF); // LSB OLED_GetResponse(); } void OLED_DrawLine(char x1, char y1, char x2, char y2, int color) { // Line drawing Serial.print(OLED_LINE); // Line Serial.print(x1); // x1 Serial.print(y1); // y1 Serial.print(x2); // x2 Serial.print(y2); // y2 // Color Serial.print(color >> 8); // MSB Serial.print(color & 0xFF); // LSB OLED_GetResponse(); } void OLED_DrawRectangle(char x, char y, char width, char height, char filled, int color) { //int color = 0xFFFF; // Rectangle drawing Serial.print(OLED_RECTANGLE); Serial.print(x); // x1 Serial.print(y); // y1 Serial.print(x+width); // x2 Serial.print(y+height); // y1 // Color Serial.print(color >> 8); // MSB Serial.print(color & 0xFF); // LSB /* if (filled == 1) { Serial.print(0x01); } // Filled else { Serial.print(0x00); } // Outline */ OLED_GetResponse(); } void OLED_DrawCircle(char x, char y, char radius, char filled, int color) { Serial.print(OLED_CIRCLE); Serial.print(x); // x Serial.print(y); // y Serial.print(radius); // radius // Color Serial.print(color >> 8); // MSB Serial.print(color & 0xFF); // LSB OLED_GetResponse(); } /* Change font format: FontType can be: OLED_FONT5X7 OLED_FONT8X8 OLED_FONT8X12 */ void OLED_SetFontSize(char FontType) { Serial.print(OLED_SETFONTSIZE); Serial.print(FontType); OLED_GetResponse(); } void OLED_DrawText(char column, char row, char font_size, char *mytext, int color) { //char mytext[] = "Arkanoid by pK"; Serial.print(0x73); // s (Formated text) //Serial.print(column); // column // Adjust to center of the screen (26 Columns at font size 0) int newCol = 13 - (strlen(mytext)/2); //Serial.print(newCol); // column Serial.print(column); // column Serial.print(row); // row Serial.print(font_size); // font size (0 = 5x7 font, 1 = 8x8 font, 2 = 8x12 font) // Color Serial.print(color >> 8); // MSB Serial.print(color & 0xFF); // LSB for (int i=0 ; i<strlen(mytext) ; i++) { Serial.print(mytext[i]); // character to write } Serial.print(0x00); // string terminator (always 0x00) OLED_GetResponse(); } void OLED_DrawSingleChar(char column, char row, char font_size, char MyChar, int color) { Serial.print(OLED_TEXTFORMATED); // T (Formated) Serial.print(MyChar); Serial.print(column); Serial.print(row); // Color Serial.print(color >> 8); // MSB Serial.print(color & 0xFF); // LSB OLED_GetResponse(); }