2023年4月21日金曜日

液晶に大きな数字を書く

秋月電子で販売している液晶ディスプレイAQM0802とAQM1602は、I2C接続でArduinoやESP32、RaspberryPiPicoなどに接続できます。動作電流が1mAなので、電池駆動したい場合などに重宝します。

ただ、文字が小さいため、温度や時刻などを表示すると空白が余ります。そこで大きな数字を表示できるようにしてみました。

(ちなみに、ここに書いた方法以外にも、FunctionSetコマンド(0x38)を送信してDHを1にすることで、縦が2倍のdoubleHeightFontを使うことができます)

RaspberryPiPicoとAQM0802の接続

  • Pico -> AQM0802またはAQM1602
  • GP20(I2C0SDA)-> SDA
  • GP21(I2C0SCL) -> SCL
  • 3V3 -> VDD
  • GND->GND

           RESETは変換基板上でVDDにプルアップされているためオープンでOK

ArduinoUNOなどの5Vデバイスで使用する場合の注意

SDA、SCLにレベル変換を入れるほうが良いと思います。

(入れなくても3.3Vにプルアップすれば動きますが、壊れても文句言わない)

Picoのボードファイルについて

mbedにする場合、SDA、SCLはGP6、GP7に固定されていますので注意が必要です。

特別こだわりがなければ、'Earle F. Philhower, III'バージョンを使ったほうがI2Cのピンを変更できたり、いろいろ便利です。

他の液晶

似たような液晶パネルに、ACM1602NIなどがありますが、キャラクタパターンが違うので使えません。

#include "AQM0802BigDigit.h"
//----- I2C interface -----
void AQM0802BigDigit::WriteCommand(uint8_t data)
{
Wire.beginTransmission(0x3E);
Wire.write(0x00);
Wire.write(data);
Wire.endTransmission(true);
}
void AQM0802BigDigit::WriteData(uint8_t data)
{
Wire.beginTransmission(0x3E);
Wire.write(0x40);
Wire.write(data);
Wire.endTransmission(true);
}
void AQM0802BigDigit::createCustomChar(int index , const uint8_t* pattern)
{
WriteCommand(0x40 + index * 8);
for (int i=0; i<8; i++) WriteData(pattern[i]);
}
void AQM0802BigDigit::setCursorAtRowAndColumn(int row, int col)
{
WriteCommand(0x80 + col * 0x40 + row);
}
void AQM0802BigDigit::init()
{
WriteCommand(0x38); // Function set
WriteCommand(0x39); // Function set
WriteCommand(0x14); // Internal OSC frequency
WriteCommand(0x73); // Contrast set
WriteCommand(0x56); // Power/ICON/Contrast set
WriteCommand(0x6c); // Follower control
delay(200);
WriteCommand(0x38); // Function set
WriteCommand(0x0c); // Display ON/OFF control
WriteCommand(0x01); // Clear Display
delay(1);
WriteCommand(0x0C); // Display ON/OFF control
createCustomChar(0,image0);
createCustomChar(1,image1);
createCustomChar(2,image2);
createCustomChar(3,image3);
createCustomChar(4,image4);
createCustomChar(5,image5);
}
void AQM0802BigDigit::displayBigDigitAtColumn(uint8_t digit, uint8_t pos_x)
{
setCursorAtRowAndColumn(pos_x,0);
WriteData(bigDigitFull[digit][0]);
WriteData(bigDigitFull[digit][1]);
setCursorAtRowAndColumn(pos_x,1);
WriteData(bigDigitFull[digit][2]);
WriteData(bigDigitFull[digit][3]);
}
void AQM0802BigDigit::displayBigDigitHalfAtColumn(uint8_t digit, uint8_t pos_x)
{
setCursorAtRowAndColumn(pos_x,0);
WriteData(bigDigitHalf[digit][0]);
setCursorAtRowAndColumn(pos_x,1);
WriteData(bigDigitHalf[digit][1]);
}
#include <Arduino.h>
#include <Wire.h>
class AQM0802BigDigit
{
private:
void WriteCommand(uint8_t data);
void WriteData(uint8_t data);
void createCustomChar(int index , const uint8_t* pattern);
void setCursorAtRowAndColumn(int row, int col);
public:
void init();
void displayBigDigitAtColumn(uint8_t digit, uint8_t pos_x);
void displayBigDigitHalfAtColumn(uint8_t digit, uint8_t pos_x);
private:
//CGRAM character
const uint8_t image0[8] = { 0b11111, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111 };
const uint8_t image1[8] = { 0b11111, 0b00001, 0b00001, 0b00001, 0b00001, 0b00001, 0b00001, 0b11111 };
const uint8_t image2[8] = { 0b11111, 0b10000, 0b10000, 0b10000, 0b10000, 0b10000, 0b10000, 0b11111 };
const uint8_t image3[8] = { 0b10000, 0b10000, 0b10000, 0b10000, 0b10000, 0b10000, 0b10000, 0b11111 };
const uint8_t image4[8] = { 0b00001, 0b00001, 0b00001, 0b00001, 0b00001, 0b00001, 0b00001, 0b11111 };
const uint8_t image5[8] = { 0b00100, 0b00100, 0b00100, 0b00100, 0b00100, 0b00100, 0b00100, 0b11111 };
//lookup table
const uint8_t bigDigitFull[10][4] = {
{0x09,0x0A,0x0B,0x0C}, //0
{0x20,0x7C,0x20,0x7C},
{0x00,0x01,0x0B,0x5F},
{0xFF,0x01,0x5F,0x0C},
{0x03,0x05,0x20,0x7C},
{0x02,0x00,0x5F,0x0C},
{0x02,0x00,0x0B,0x0C},
{0x09,0x0A,0x20,0x7C},
{0x02,0x01,0x0B,0x0C},
{0x02,0x01,0x5F,0x0C} // 9
};
const uint8_t bigDigitHalf[13][2] = {
{0x20,0x20}, // ' '
{0x7C,0x7C},
{0x01,0x0B},
{0x01,0x0C},
{0x66,0x7C}, //4
{0x02,0x0C},
{0x02,0x66}, //6
{0x0A,0x7C},
{0x4F,0x4F}, //8
{0x4F,0x0C}, //9
{0x20,0x2E}, //.
{0xA5,0xA5}, //:
{0xFF,0x20} //-
};
};
#include <Wire.h>
#include "AQM0802BigDigit.h"
// ------------------------------------------------------------------------------------------------------
// AQM1602, AQM0802
// This source code is written for Raspberry Pi pico, but it can also be used with ArduinoUNO by modifying the Wire settings.
// ## Raspberry Pi pico
// Please use 'Earle F. Philhower, III' version.
// When using the 'mbed' version, some changes are required in the wire definition, and the SDA and SCL port are fixed.
const uint8_t PIN_I2CSDA = 20;
const uint8_t PIN_I2CSCL = 21;
AQM0802BigDigit lcd;
void setup() {
Wire.setSDA(PIN_I2CSDA);
Wire.setSCL(PIN_I2CSCL);
Wire.begin();
lcd.init();
}
void loop() {
//Sample1 FM frequency
uint16_t freq = 740;
while (freq != 1080) {
lcd.displayBigDigitHalfAtColumn((freq / 1000 == 1),0);
lcd.displayBigDigitAtColumn((freq / 100) % 10, 1);
lcd.displayBigDigitAtColumn((freq / 10) % 10, 3);
lcd.displayBigDigitHalfAtColumn(10,5); // .
lcd.displayBigDigitAtColumn((freq) % 10, 6);
freq++;
delay(10);
}
//Sample2 clock
uint8_t time_hour = 0;
uint8_t time_min = 0;
while (time_hour < 13) {
time_min = 0;
while (time_min < 60) {
lcd.displayBigDigitHalfAtColumn((time_hour / 10), 0);
lcd.displayBigDigitAtColumn((time_hour % 10),1);
lcd.displayBigDigitHalfAtColumn(11,3); // :
lcd.displayBigDigitAtColumn((time_min / 10),4);
lcd.displayBigDigitAtColumn((time_min % 10),6);
time_min++;
delay(10);
}
time_hour++;
}
}


0 件のコメント:

コメントを投稿