エントリー

カテゴリー「LCD表示器」の検索結果は以下のとおりです。

AQM0802A-FLW-GBWを使えるようにする

良く利用しているI2C接続LCDのAQM1602XA-RN-GBWは16×2表示でコストパフォーマンスに優れてるが基板の中央等に載せるとその大きさで他のボタンなどと干渉し配置を悩まされることがある

IMG_20180120_164042.jpg

そこで8×2表示のAQM0802A-FLW-GBW(バックライト付き)をAQM0802A-RN-GBWにバックライトが付いただけだと思って購入

資料を比べても異なるのはバックライトのみだったので同じように使えるはず

またAQM1602XA-RN-GBWと表示文字数は異なるが表示用DDRAMは内部で同じなのでライブラリ等の修正は必要ない

しかしピンのピッチはAQM0802A-RN-GBWと同じ1.5だがバックライト用のピンがあるので同じ変換基板は利用できないしAQM1602XA-RN-GBW用はピッチが1.27でピン配置も異なり不可

つまり取付用の変換基板は作製しなければならない

IMG_20180120_163956.jpgIMG_20180120_164131.jpg

2.54や2.0の基板では厳しいので64×64の1.27ピッチ基板を試すと挿せるがパーツを載せるのが表面実装品でないと大変そうだ

IMG_20180123_195210.jpgIMG_20180123_195233.jpg

そこで1.27から2.54の変換基板を利用する

IMG_20180123_195317.jpgIMG_20180123_195401.jpg

10ピン変換なので1ピン余るため中央を外し5,4ピンに分けた

IMG_20180123_195753.jpgIMG_20180123_195804.jpg

そして出力ピンをAQM1602XA-RN-GBWと同じにしてパーツを載せる(少しは配置を考えたつもりだが汚い)

IMG_20180129_193537.jpgIMG_20180129_193549.jpg

早速テストしてみると

IMG_20180129_193830.jpg

載せる方向が思っていたのと上下逆だった(逆にすれば使えるので問題はない)

次に深刻な問題として1行目は表示されるが2行目が表示されていない

そして1行目が表示されていたためソフトの問題だと思い込んでしまって一週間も嵌ることになる・・・

  • コントラストを何度も調整したり
  • 仕様書を眺めまわしソフト的な制御を変更したり
  • I2Cアドレスを確認したり
  • 3.3Vでないとダメなのかと試してみたり
  • ネットで同様の問題はないか検索したり

色々と考え試したが解決しない

で,ようやく休日を迎えたので別のAQM0802A-FLW-GBWをブレッドボード上で試してみると2行目が表示されてしまった

つ・ま・り・・・ハードの問題だったのだ(元々不良だったのか基板に載せる際に壊したのかは不明)

IMG_20180206_185038.jpgIMG_20180206_185126.jpg

今度はLCDの方向とパーツの配置を考えて作り直し(またも美しくないが)正常動作を確認

IMG_20180206_185251.jpg

(備考)
  • LCDのピン付近は熱に弱いので注意(半田付けで熱を逃さないと簡単に溶ける)
  • バックライトは5Vでの動作も考え51Ωを入れた
  • 1ピンは使用しないので変換基板に8ピンを上手く割り振れば他のパーツの配置が良くなるかもしれない
  • 仕様では3.3V用となっているが(コントラスト設定時の)昇圧指定を無くせば5Vでも使える
(参考)16×2での表示

IMG_20180206_185336.jpg

 

キャラクタLCD表示用ライブラリ

秋月電子のI2C接続小型キャラクタLCD(AQM1602XA)を利用するための表示用ライブラリを作ることにした

電子負荷の消費電流および電源電圧の表示部を作製しようとしたところ今後も良く使いそう(毎日でないので使い方を忘れてしまうから)なのでライブラリにしておこうと考えた訳である

ライブラリ化する方法と注意点

  • ライブラリはIDEの環境設定で指定したフォルダに新規のライブラリフォルダを作ってファイルを置く
  • 必要ファイルは,XXX.hとXXX.cppとなる(その他は無くても問題なし,.cではダメだった)
  • XXXは同じでなくてはならない
  • 新規のライブラリフォルダ名はXXXでなくても良い

 

AQM1602LCD.h

#define _AQM1602_H_
#if ARDUINO >= 100
 #include "Arduino.h"
#else
 #include "WProgram.h"
#endif

#define LCD_ADDR 0x3E

void LCD_clearScreen(void);
void LCD_setLocate(int col, int row);
void LCD_putChar(byte c);
void LCD_putString(byte *str);
void LCD_init3();
void LCD_init5();
#endif /* AQM1602LIB_H */

AQM1602LCD.cpp

// LCD_init3        - LCDの初期化(3.3V)
// LCD_init5        - LCDの初期化(5V)
//
// LCD_clearScreen  - LCDモジュールの画面をクリア
// LCD_setLocate    - LCDモジュール画面内のカーソル位置を移動
// LCD_putChar      - LCDにデータを1バイト出力
// LCD_putString    - LCDに文字列データを出力
//

#include <Wire.h>
#include "AQM1602LCD.h"

// LCDにコマンドを送信
//
static void LCD_writeCommand(byte command) {
    Wire.beginTransmission(LCD_ADDR);    // スタートコンディション
    Wire.write(0x00);                    // control byte の送信(コマンドを指定)
    Wire.write(command);                // command byte の送信
    Wire.endTransmission();                // ストップコンディション
    delay(10);
}

// LCDにデータを送信
//
static void LCD_writeData(byte data) {
    Wire.beginTransmission(LCD_ADDR);    // スタートコンディション
    Wire.write(0x40);                    // control byte の送信(データを指定)
    Wire.write(data);                    // data byte の送信
    Wire.endTransmission();                // ストップコンディション
    delay(1);
}

// LCDの初期化
//
static void LCD_init(int volt) {
    Wire.begin();

    delay(100);
    LCD_writeCommand(0x38); delay(20);        // Function set
    LCD_writeCommand(0x39); delay(20);        // IS=1
    LCD_writeCommand(0x14); delay(20);        // Internal OSC frequency

    if(volt == 3) {
        // 3.3V
        LCD_writeCommand(0x73); delay(20);    // Contrast set
        LCD_writeCommand(0x56); delay(20);    // POWER/ICON/Contrast control
    } else /* if(volt == 5) */ {
        // 5V
        LCD_writeCommand(0x7A); delay(20);    // Contrast set
        LCD_writeCommand(0x52); delay(20);    // POWER/ICON/Contrast control
    }
    LCD_writeCommand(0x6C); delay(20);        // Follower control
    LCD_writeCommand(0x38); delay(20);        // Function set
    LCD_writeCommand(0x01); delay(20);        // Clear Display
    LCD_writeCommand(0x0C); delay(20);        // Display ON
    LCD_writeCommand(0x06); delay(20);        // Entry Mode
}

// LCDの初期化(3.3V)
//
void LCD_init3() {
    LCD_init(3);
}

// LCDの初期化(5V)
//
void LCD_init5() {
    LCD_init(5);
}

// LCDモジュールの画面をクリア
//
void LCD_clearScreen(void) {
    LCD_writeCommand(0x01);                // Clear Display
}

// LCDモジュール画面内のカーソル位置を移動
//    col : 横(列)方向のカーソル位置(0-15)
//    row : 縦(行)方向のカーソル位置(0-1)
//
void LCD_setLocate(int col, int row) {
    static int row_offsets[] = { 0x00, 0x40 } ;
    // Set DDRAM Adddress : 00H-0FH,40H-4FH
    LCD_writeCommand(0x80 | (col + row_offsets[row]));
}

// LCDにデータを1バイト出力
//      c :  出力する文字データを指定
//
void LCD_putChar(byte c) {
    LCD_writeData(c);
}

// LCDに文字列データを出力
//    str :  出力する文字列
//
void LCD_putString(byte *str) {
    while(*str) LCD_writeData(*str++);
}

ライブラリインタフェースはコメントのとおり

ヘッダーファイルの

#include "Arduino.h"

を,忘れがちなので忘れないようにする事

(追加:2017.01.22)

C++に書き換えた

注意点
  • コンストラクタで電圧の指定とかやってみたが上手く動作しないので保留(現状はsetup()を呼び出す仕様)
  • 割込み禁止で使うとハングアップするようだ
  • C版も使用しているので名称を変更

AQMI2CLCD.h

//秋月電子通商 I2C接続小型キャラクタLCDモジュール
//    AQM0802A-RN-GBW(8x2行)
//    AQM0802A-FLW-GBW(8x2行,バックライト付)
//    AQM1602XA-RN-GBW(16x2行)
//
//Sitronix ST7032 CONTROLED
//    電源電圧:2.7~5.5V
//    インターフェース:I2C
//    I2Cアドレス:0x3E
//    I2Cスピード: 最大400kHz
//    使用可能温度:-30~+85℃
//
#ifndef _AQMI2CLCD_H_
#define _AQMI2CLCD_H_
#if ARDUINO >= 100
 #include <Arduino.h>
#else
 #include <WProgram.h>
#endif

#define AQMI2CLCD_ADDR 0x3E

class AQMI2CLCD {
    public:
//        AQMI2CLCD();
        void setup();
        void setup(int);
        void clearScreen(void);
        void setLocate(int, int);
        void putChar(char);
        void putString(char *);
        void putString(int);
};

#endif /* AQMI2CLCD_H */

AQMI2CLCD.cpp

//秋月電子通商 I2C接続小型キャラクタLCDモジュール
//
// コンストラクタ
// void AQMI2CLCD()
//
// void setup
// void setup(int)
//        3        - LCDの初期化(3.3V)
//        5        - LCDの初期化(5V)
// void clearScreen    - LCDモジュールの画面をクリア
// void setLocate    - LCDモジュール画面内のカーソル位置を移動
// void putChar        - LCDにデータを1バイト出力
// void putString    - LCDに文字列データを出力
//
#include <AQMI2CLCD.h>
#include <Wire.h>

//AQMI2CLCD::AQMI2CLCD() {}

// LCDにコマンドを送信
//
static void LCD_writeCommand(byte command) {
    Wire.beginTransmission(AQMI2CLCD_ADDR);    // スタートコンディション
    Wire.write(0x00);                        // control byte の送信(コマンドを指定)
    Wire.write(command);                    // command byte の送信
    Wire.endTransmission();                    // ストップコンディション
    delay(10);
}

// LCDにデータを送信
//
static void LCD_writeData(byte data) {
    Wire.beginTransmission(AQMI2CLCD_ADDR);    // スタートコンディション
    Wire.write(0x40);                        // control byte の送信(データを指定)
    Wire.write(data);                        // data byte の送信
    Wire.endTransmission();                    // ストップコンディション
    delay(1);
}

// LCDの初期化
//
static void LCD_init(int volt) {
    Wire.begin();

    delay(100);
    LCD_writeCommand(0x38); delay(20);        // Function set
    LCD_writeCommand(0x39); delay(20);        // IS=1
    LCD_writeCommand(0x14); delay(20);        // Internal OSC frequency

    if(volt == 3) {
        // 3.3V
        LCD_writeCommand(0x73); delay(20);    // Contrast set
        LCD_writeCommand(0x56); delay(20);    // POWER/ICON/Contrast control
    } else /* if(volt == 5) */ {
        // 5V
        LCD_writeCommand(0x7A); delay(20);    // Contrast set
        LCD_writeCommand(0x52); delay(20);    // POWER/ICON/Contrast control
    }
    LCD_writeCommand(0x6C); delay(20);        // Follower control
    LCD_writeCommand(0x38); delay(20);        // Function set
    LCD_writeCommand(0x01); delay(20);        // Clear Display
    LCD_writeCommand(0x0C); delay(20);        // Display ON
    LCD_writeCommand(0x06); delay(20);        // Entry Mode
}

// LCDセットアップ
//
void AQMI2CLCD::setup() {
    LCD_init(5);
}
void AQMI2CLCD::setup(int volt) {
    LCD_init(volt);
}

// LCDモジュールの画面をクリア
//
void AQMI2CLCD::clearScreen(void) {
    LCD_writeCommand(0x01);                // Clear Display
}

// LCDモジュール画面内のカーソル位置を移動
//    col : 横(列)方向のカーソル位置(0-15)
//    row : 縦(行)方向のカーソル位置(0-1)
//
void AQMI2CLCD::setLocate(int col, int row) {
    static int row_offsets[] = { 0x00, 0x40 } ;
    // Set DDRAM Adddress : 00H-0FH,40H-4FH
    LCD_writeCommand(0x80 | (col + row_offsets[row]));
}

// LCDにデータを1バイト出力
//      c :  出力する文字データを指定
//
void AQMI2CLCD::putChar(char c) {
    LCD_writeData(c);
}

// LCDに文字列データを出力
//    str :  出力する文字列
//
void AQMI2CLCD::putString(char *str) {
    while(*str) LCD_writeData(*str++);
}
void AQMI2CLCD::putString(int n) {
    char bf[16];
    sprintf(bf, "%d\0", n);
    char *str = bf;
    while(*str) LCD_writeData(*str++);
}

予告なく改良

温湿度をFSTN液晶モジュールで表示

温湿度センサ(DHT11)の続きで,温湿度データをFSTN液晶モジュールで表示してみた

1

フォントをそこそこのサイズにしないと見え難いためu8glibのソースを見ながら適切なフォントを選択

#include "U8glib.h"
#include "DHT.h"

U8GLIB_MINI12864 u8g(10, 9);
DHT dht(2, DHT11);

void draw(float h, float hic) {
    u8g.setFont(u8g_font_helvR24);
    u8g.setPrintPos(4, 28);
    u8g.print(hic);
    u8g.setPrintPos(94, 28);
    u8g.print("'C");
    u8g.setPrintPos(4, 60);
    u8g.print(h);
    u8g.setPrintPos(94, 60);
    u8g.print("%");
}
void setup(void) {
    dht.begin();
    u8g.setContrast(190);
}
void loop(void) {

    // Wait a few seconds between measurements.
    delay(2000);

    float h = dht.readHumidity();
    float t = dht.readTemperature();
    if(isnan(h) || isnan(t)) {
        Serial.println("Failed to read from DHT sensor!");
        return;
    }
    float hic = dht.computeHeatIndex(t, h, false);

    // picture loop
    u8g.firstPage();
    do {
        draw(h, hic);
    } while(u8g.nextPage());
}

ところでデータシートを見ると,この温湿度センサ(DHT11)は,やっぱ廉価版のせいか小数点以下のデータはない(上で表示している小数点以下は補正で出てるだけ)

以下抜粋

Data consists of decimal and integral parts.
A complete data transmission is 40bit, and the sensor sends higher data bit first.
Data format: 8bit integral RH data + 8bit decimal RH data + 8bit integral T data + 8bit
decimal T data + 8bit check sum.
If the data transmission is right, the check-sum should be the last 8bit of "8bit integral
RH data + 8bit decimal RH data + 8bit integral T data + 8bit decimal T data".

要約すると,

データは40ビットでMSBから送られてくる

つまり全体は5バイト,最初の2バイトが湿度,次の2バイトが温度でそれぞれ1バイト目が整数部,2バイト目が小数点以下部となる

最後の1バイトはCRC(チェックサム)で1~4バイトを加算した数(オーバーフロー部は捨てる)

そして温湿度センサ(DHT11)の場合は,温湿度の2バイト目の小数点以下が必ず0になっている

湿度は製品で値がまちまちなようなので小数点以下はいらないかなと思うけど,気温はせめて0.5位までは欲しいかなと思うのでちょっと残念(使い場所を考えないといけないな)

 

次は大気圧センサを追加してみる

LPS25H

大気圧だけでなく温度も取得できるようだ

aitendoのFSTN液晶モジュール表示確認

最初atmega168しか3.3V版を用意してなかったので,このままu8glibのサンプルを実行しようとしてらメモリが足りなかった

なのでatmega328の3.3Vを作ることに・・・

atmega328

いつのもように3.3版にしたuncompatinoを使う(初期化方法はこちら

uncompatino

3.3V版にしてブートローダ書き込み後FSTN液晶モジュールを取り付け表示確認

接続

 5    LEDA       +3.3V(バックライト)
 6    VSS        GND
 7    VDD        +3.3V
             (arduino)            (ATMEGA328P)
 8    SCK        13                    19
 9    SDA        11                    17
10    RS          9                    15
11    RST  Reset or +3.3V            +3.3V
12    CS         10                    16

サンプルプログラム

#include "U8glib.h"

U8GLIB_MINI12864 u8g(10, 9);

void draw(void) {
  // graphic commands to redraw the complete screen should be placed here
  u8g.setFont(u8g_font_unifont);
  //u8g.setFont(u8g_font_osb21);
  u8g.drawStr( 0, 22, "Hello World!");
}
void setup(void) {
  u8g.setContrast(190);
}
void loop(void) {
  // picture loop
  u8g.firstPage();
  do {
    draw();
  } while( u8g.nextPage() );
 
  // rebuild the picture after some delay
  delay(50);
}

サンプル

他のu8glibサンプルも試して確認

キーとなるのは以下の2箇所

デバイス指定

U8GLIB_MINI12864 u8g(10, 9);

コントラスト

void setup(void) {
    u8g.setContrast(160);
}

ラジオペンチさんとか参考にさせていただきました

ページ移動

  • ページ
  • 1
  • 2

ユーティリティ

タグクラウド

検索

エントリー検索フォーム
キーワード

Feed