fc2ブログ

シフトレジスタSN74HC595Nで遊ぶ

 以前のブログで「3×3のLED cube」を作製し、Arduino(AEーATMEGA328-MINI)のI/Oで制御した件をお話ししました。cubeのサイズを大きくすると制御するI/O点数も増えるため、シフトレジスタを使う事例を多く見かけました。シフトレジスタは今まで触ったことがなかったので、秋月でSN74HC595Nを購入し、早速使ってみました。AE_ShiftRegister_190728.png シフトレジスタについては、知識が全くなかったので、このサイトの全面的なバックアップの元で勉強しました。ありがとうございました
 ArduinoマイコンとしてESP-WROOM-02(ESP8266)を用い、以下の回路を組みました。ShiftRegister_Circuit_190728.png プログラムは参考サイトのものを転用させていただきました。以下の2つのパターンの動作確認をしました。
//Pattern 1
#define SRCLK 12
#define RCLK 13
#define SER 14

void setup() {
pinMode(SRCLK, OUTPUT);
pinMode(RCLK, OUTPUT);
pinMode(SER, OUTPUT);
}

void loop() {
// 入力状態をHIGHにする
digitalWrite(SER, HIGH);

for (int i=0; i<8; i++) {
// シフトレジスタをシフトさせてSERピンの状態を記憶させる
digitalWrite(SRCLK, LOW);
digitalWrite(SRCLK, HIGH);

// シフトレジスタの状態をストレージレジスタへ反映させる
digitalWrite(RCLK, LOW);
digitalWrite(RCLK, HIGH);

delay(200);

// 以降の入力状態をLOWにする
digitalWrite(SER, LOW);
}
}
//Pattern 2
#define SRCLK 12
#define RCLK 13
#define SER 14

void setup() {
pinMode(SRCLK, OUTPUT);
pinMode(RCLK, OUTPUT);
pinMode(SER, OUTPUT);
}

// 点灯パターン(1=点灯, 0=消灯)
const uint8_t PATTERNS[] = {
0b10000001,
0b01000010,
0b00100100,
0b00011000,
0b00011000,
0b00100100,
0b01000010,
0b10000001,
};

void loop() {

// 点灯パターンの数
int max_pattern = sizeof(PATTERNS)/sizeof(PATTERNS[0]);

for (uint8_t i=0; i // 8ビット分のデータをシフトレジスタへ送る
shiftOut(SER, SRCLK, LSBFIRST, PATTERNS[i]);

// シフトレジスタの状態をストレージレジスタへ反映させる
digitalWrite(RCLK, LOW);
digitalWrite(RCLK, HIGH);

delay(200);
}
}
Pattern1、2の実際の動きは以下の動画の通りです。 触ってみることで、漠然とですが、シフトレジスタの動作イメージが理解できました。次は、自分で応用して、何か作ってみたいと思います。
スポンサーサイト



I2C通信LCDを使う

 以前、ESP8266に接続している温湿度気圧センサ(BME280)のデータをRaspi ZeroにFTPで飛ばして、保存するお話をしました。センサデータをRaspi Zeroに保存したり、アクセスポイントであるESP8266に接続してリアルタイムのデータを閲覧できるようになりました。ただ、PCや携帯端末を使わずに、簡単にリアルタイムのデータを見ることができればいいなと、ふと思いました(いまさらですが・・)。

 早速、LCDをつけてデータ表示をしようと思い立ち、同時に、過去PICを使ってLCDを動作させるのに苦労したことを思い出しました。PIC-PC間をUSART通信(Universal Synchronous Asynchronous Receiver Transmitter)を使って、データを送受信して、LCDに表示させるお話でした。今回、センサデータはI2C通信で取っており、I2Cデバイスは並列で接続できることから、I2C通信のLCD表示にトライしました。シリアル通信にはいろいろ方式(I2C、SPI、USART等)があり、このサイトにうまくまとめられています。

 秋月で以下のLCDモジュールを購入し、
 【M-09109】I2C接続小型LCDモジュール(8x2行)ピッチ変換モジュール(完成品)
過去のブログの内容を参考に、以下の通り配線しました。i2c_LCD_circut_190707.png乾電池駆動で3.3V出力の昇圧DC-DCコンバータを使いました。

 Arduinoのコードは以下の通りです。LCD用のライブラリもインストールしておきます。i2c_LCD_library_190707.pngまた、以下の関数は、以前のブログに記載のコードと同じなので割愛します。
readTrim、writeReg、readData、calibration_T、calibration_P、calibration_H
#include <Wire.h>
#include <FaBoLCDmini_AQM0802A.h>

FaBoLCDmini_AQM0802A lcd;
#define BME280_ADDRESS 0x76
unsigned long int hum_raw,temp_raw,pres_raw;
signed long int t_fine;

uint16_t dig_T1;
int16_t dig_T2;
int16_t dig_T3;
uint16_t dig_P1;
int16_t dig_P2;
int16_t dig_P3;
int16_t dig_P4;
int16_t dig_P5;
int16_t dig_P6;
int16_t dig_P7;
int16_t dig_P8;
int16_t dig_P9;
int8_t dig_H1;
int16_t dig_H2;
int8_t dig_H3;
int16_t dig_H4;
int16_t dig_H5;
int8_t dig_H6;

void setup()
{
uint8_t osrs_t = 1; //Temperature oversampling x 1
uint8_t osrs_p = 1; //Pressure oversampling x 1
uint8_t osrs_h = 1; //Humidity oversampling x 1
uint8_t mode = 3; //Normal mode
uint8_t t_sb = 5; //Tstandby 1000ms
uint8_t filter = 0; //Filter off
uint8_t spi3w_en = 0; //3-wire SPI Disable

uint8_t ctrl_meas_reg = (osrs_t <<5) | (osrs_p << 2) | mode;
uint8_t config_reg = (t_sb << 5) | (filter << 2) | spi3w_en;
uint8_t ctrl_hum_reg = osrs_h;

Serial.begin(115200);
Wire.begin(4,5);

writeReg(0xF2,ctrl_hum_reg);
writeReg(0xF4,ctrl_meas_reg);
writeReg(0xF5,config_reg);
readTrim();

lcd.begin();
lcd.setCursor(0, 0);
lcd.print("Hello!!");
lcd.setCursor(0, 1);
lcd.print("Start...");
delay(2000);
}

void loop()
{
double temp_act = 0.0, press_act = 0.0,hum_act=0.0;
signed long int temp_cal;
unsigned long int press_cal,hum_cal;
char temp_str_t[8], hum_act_t[8], press_str_t[8];

readData();

temp_cal = calibration_T(temp_raw);
press_cal = calibration_P(pres_raw);
hum_cal = calibration_H(hum_raw);
temp_act = (double)temp_cal / 100.0;
press_act = (double)press_cal / 100.0;
hum_act = (double)hum_cal / 1024.0;
Serial.print("TEMP : ");
Serial.print(temp_act);
Serial.print(" DegC PRESS : ");
Serial.print(press_act);
Serial.print(" hPa HUM : ");
Serial.print(hum_act);
Serial.println(" %");

dtostrf(temp_act,5,1,temp_str_t);
temp_str_t[5] = ' ';
temp_str_t[6] = 223;
temp_str_t[7] = 'C';
lcd.setCursor(0,0);
lcd.print("Temp. ");
lcd.setCursor(0,1);
lcd.print(temp_str_t);
delay(2000);

dtostrf(hum_act,6,1,hum_act_t);
hum_act_t[6] = ' ';
hum_act_t[7] = '%';
lcd.setCursor(0,0);
lcd.print("Humid. ");
lcd.setCursor(0,1);
lcd.print(hum_act_t);
delay(2000);

dtostrf(press_act,4,0,press_str_t);
press_str_t[4] = ' ';
press_str_t[5] = 'h';
press_str_t[6] = 'P';
press_str_t[7] = 'a';
lcd.setCursor(0,0);
lcd.print("Press. ");
lcd.setCursor(0,1);
lcd.print(press_str_t);
delay(2000);
}
 最後に動作確認です。[広告]

こんなに簡単にLCD表示ができるなんて、PICで苦労したことが嘘のようです。今後、気楽にLCDを使えそうです。

ご訪問者数

(Since 24 July, 2016)

タグクラウド


プロフィール

Dr.BobT

Author: Dr.BobT
興味のおもむくままに生涯考え続けるエンジニアでありたい。

月別アーカイブ

メールフォーム

名前:
メール:
件名:
本文: