最終更新:2010-02-04 (木) 09:16:51 (5185d)  

Arduino/µOLED
Top / Arduino / µOLED

4D SystemsµOLEDシリーズをArduinoで動かすメモ

対象

メモ

http://jennylc.com/4d/

に置いてあるライブラリは呼び出している関数(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();

}

参考