http://qiita.com/7of9/items/c3c1acaf46822d7b2754
の続き
文字列を任意の位置に表示する関数を追加
void AQM0802_PutMessage(String msg, uint8_t x_st1, uint8_t y_st1)
{
// _st1 : index starting from 1
if ((x_st1 > kMaxXsize) || (y_st1 > kMaxYsize)) {
return; // error
}
uint8_t pos = 0x80 | ((y_st1 - 1) * 0x40);
pos = pos | (x_st1 - 1);
AQM0802_WriteSingleInstruction(pos);
AQM0802_WriteData( (uint8_t *)msg.c_str(), msg.length() );
}
準備手順
以下の準備を参照
http://qiita.com/7of9/items/c3c1acaf46822d7b2754
code (v0.3)
esp8266_160217_AQM0802.ino
#include <Wire.h>
void setup() {
Serial.begin(115200);
Serial.println("");
Wire.begin(); // (SDA,SCL) Default 4 and 5
AQM0802_Initialize(/* cursorOn=*/true, /* cursorPosOn=*/true, /* contrast=*/7);
// Test_AQM0802_cursorOn_posOff_contrastLow();
// Test_AQM0802_cursorOn_posOn_contrastLow();
// Test_AQM0802_cursorOn_posOn_contrastHigh();
displayDateTime();
}
void displayDateTime()
{
AQM0802_PutMessage("20160218", /* x_st1=*/1, /* y_st1=*/1);
AQM0802_PutMessage("06:57", /* x_st1=*/3, /* y_st1=*/2);
//Test_AQM0802_showDateTime("20160218", "06:57");
}
void loop()
{
static bool bfOn = true;
if (bfOn) {
displayDateTime();
} else{
AQM0802_Clear();
}
bfOn = !(bfOn);
delay(3000);
}
AQM0802lib.ino
#include <Wire.h>
/*
* v0.3 2016 Feb. 18
* - add message display function
* + add Test_AQM0802_showDateTime()
* + add AQM0802_PutMessage()
* v0.2 2016 Feb. 17
* - add test functions()
* + add Test_AQM0802_cursorOn_posOn_contrastHigh()
* + add Test_AQM0802_cursorOn_posOn_contrastLow()
* + add Test_AQM0802_cursorOn_posOff_contrastLow()
* v0.1 2016 Feb. 17
* - add AQM0802_Initialize()
* - add AQM0802_Clear()
* - add AQM0802_WriteData()
* - add AQM0802_WriteInstruction()
* - add writeToDevice()
*
* -------
* Special thanks to exabugs for ( http://qiita.com/exabugs/items/9d1b66aa1d22805afbc8 )
*/
static const uint8_t kDeviceAddr = 0x3e;
static const int kMaxXsize = 8;
static const int kMaxYsize = 2;
static uint8_t ControlByteList[] = {
0x00, // Instruction write operation. ( Co=0, Rs=0 )
0x40, // Data write operation. ( Co=0, Rs=1 )
};
enum {
TYPE_INSTRUCITON = 0,
TYPE_DATA,
};
//---------------------------------------------------------------------------------
// private functions ---------------------------
void writeToDevice(int type, uint8_t *dataByte, size_t len)
{
for (int idx = 0; idx < len; idx++) {
Wire.beginTransmission(kDeviceAddr);
Wire.write(ControlByteList[type]);
Wire.write(dataByte[idx]);
Wire.endTransmission();
delayMicroseconds(27); // 26.3us
}
}
//---------------------------------------------------------------------------------
// public functions ---------------------------
void AQM0802_WriteSingleInstruction(uint8_t data)
{
size_t len = 1;
uint8_t list[] = {data};
writeToDevice(TYPE_INSTRUCITON, list, len);
}
void AQM0802_WriteInstructions(uint8_t *data, int len)
{
writeToDevice(TYPE_INSTRUCITON, data, len);
}
void AQM0802_WriteData(uint8_t *data, size_t len)
{
writeToDevice(TYPE_DATA, data, len);
}
void AQM0802_Clear()
{
AQM0802_WriteSingleInstruction(0x01);
}
void AQM0802_Initialize(bool cursorOn, bool cursorPosOn, uint8_t contrast)
{
//
delay(40); // Wait time > 40ms after VDD stable
// Function set
AQM0802_WriteSingleInstruction(0x38);
// Function set
AQM0802_WriteSingleInstruction(0x39);
// Internal OSC frequency
AQM0802_WriteSingleInstruction(0x14);
// { Contrast set -----------------------------
uint8_t ctrst = contrast;
if (ctrst > 0b1111) {
ctrst = 0b1111;
}
AQM0802_WriteSingleInstruction(0x70 | ctrst);
// } Contrast set -----------------------------
// Power/ICON/Contrast control
AQM0802_WriteSingleInstruction(0x56);
// Follower control
AQM0802_WriteSingleInstruction(0x6C);
// Wait time > 200mS (for power stable)
delay(200);
// Function set
AQM0802_WriteSingleInstruction(0x38);
// { Display ON/OFF control -----------------------
uint8_t extra = 0x0;
if (cursorOn) {
extra = extra | 0b10;
}
if (cursorPosOn) {
extra = extra | 0b11;
}
AQM0802_WriteSingleInstruction(0x0C | extra);
// } Display ON/OFF control -----------------------
// Clear Display
AQM0802_WriteSingleInstruction(0x01);
// Wait time > 1.08ms
delay(2);
}
void AQM0802_PutMessage(String msg, uint8_t x_st1, uint8_t y_st1)
{
// _st1 : index starting from 1
if ((x_st1 > kMaxXsize) || (y_st1 > kMaxYsize)) {
return; // error
}
uint8_t pos = 0x80 | ((y_st1 - 1) * 0x40);
pos = pos | (x_st1 - 1);
AQM0802_WriteSingleInstruction(pos);
AQM0802_WriteData( (uint8_t *)msg.c_str(), msg.length() );
}
//---------------------------------------------------------------------------------
// test functions ---------------------------
void Test_AQM0802_cursorOn_posOff_contrastLow()
{
AQM0802_Initialize(/* cursorOn=*/true, /* cursorPosOn=*/false, /* contrast=*/1);
}
void Test_AQM0802_cursorOn_posOn_contrastLow()
{
AQM0802_Initialize(/* cursorOn=*/true, /* cursorPosOn=*/true, /* contrast=*/1);
}
void Test_AQM0802_cursorOn_posOn_contrastHigh()
{
AQM0802_Initialize(/* cursorOn=*/true, /* cursorPosOn=*/true, /* contrast=*/15);
}
void Test_AQM0802_showDateTime(String datstr, String timstr)
{
AQM0802_PutMessage(datstr, /* x_st1=*/1, /* y_st1=*/1);
AQM0802_PutMessage(timstr, /* x_st1=*/3, /* y_st1=*/2);
}
動作
3秒おきに以下の A または B を実行する。
- A. 日時の表示
- B. 画面クリア
備考
メッセージのWrap機能はまだつけてない。
(未検証だが、そのままWrapされるかもしれない。アドレスの計算を考えて)
(追記 2016/02/20)
確認したところ、Wrapは自動ではされない。
文字あふれ時にWrapする処理に変更が必要。