INT_3:『ワードカウンター』試作品1号とコード

 職業訓練校で制作したワードカウンター(試作品1号)をお見せします。

ワードカウンター試作品1号




コード

#include <Wire.h> // 2線による通信を行うためのI2C通信ライブラリ

uint8_t DEVICE_ADDRESS = 0x3E; // デバイスアドレス(スレーブ)

// 変数各種
long int cntA = 0; // 総カウント用
long int cntB = 0; // 文字数計算用
int sec = 0; // 秒
int min = 0; // 分
int hour = 0; // 時
float num = 3.2; // 文字数変換基準値
int tmpA = 0; // 値退避用
int tmpB = 0; // 値退避用
int Wcnt = 0; // 文字数用

// 表示値格納用
char cCntA[16];
char cCntB[16];
char cSec[16];
char cMin[16];
char cHour[16];
char cNum[16];
char cAval[16];
char cWcnt[16];

// 表示値変数用
String stCntA;
String stCntB;
String stSec;
String stMin;
String stHour;
String stNum;
String stAval;
String stWcnt;
String stSet;

// 音センサー関連
int d_val; // digital用変数
float a_val; // analog用変数

// LED関係
const int led03 = 3; // LED検知
const int led04 = 4; // LED音量ボリューム
const int led05 = 5; // LED音量ボリューム
const int led06 = 6; // LED音量ボリューム
const int led07 = 7; // LED音量ボリューム
const int led08 = 8; // LED音量ボリューム

// ボタン関連
int buttonBpin11 = 11; // 文字数カウント基準設定(+0.1)
int buttonBpin12 = 12; // 文字数カウント基準設定(-0.1)
int buttonBpin13 = 13; // リセットボタン

// 音センサー関連
const int digitalPin = 2; // センサ D0出力接続先
const int analogPin = A0; // センサ A0出力接続先

// スケッチが実行された時に1度だけ実行される指令 デバイスの初期化などを行う
void setup() {
pinMode(led03, OUTPUT); // LED 03番ピンを出力指定
pinMode(led04, OUTPUT); // LED 04番ピンを出力指定
pinMode(led05, OUTPUT); // LED 05番ピンを出力指定
pinMode(led06, OUTPUT); // LED 06番ピンを出力指定
pinMode(led07, OUTPUT); // LED 07番ピンを出力指定
pinMode(led08, OUTPUT); // LED 08番ピンを出力指定
pinMode(buttonBpin11, INPUT_PULLUP); // BUTTON 11番ピンをHighにする
pinMode(buttonBpin12, INPUT_PULLUP); // BUTTON 12番ピンをHighにする
pinMode(buttonBpin13, INPUT_PULLUP); // BUTTON 13番ピンをHighにする
Wire.begin(); // LCD マスタとしてI2Cバスに接続する
init_LCD(); // LCD 初期設定
writeCommand(0x02); // LCD カーソルをホームへ戻す
pinMode(digitalPin, INPUT); // 音 2番ピンを入力指定
Serial.begin(9600); // シリアル通信のデータ転送レートを9600bpsで指定
}

// LCD関係 データ書き込み
void writeData(byte t_data)
{
Wire.beginTransmission(DEVICE_ADDRESS);
Wire.write(0x40);
Wire.write(t_data);
Wire.endTransmission();
delay(1);
}

// LCD関係 コマンド書き込み
void writeCommand(byte t_command)
{
Wire.beginTransmission(DEVICE_ADDRESS);
Wire.write(0x00);
Wire.write(t_command);
Wire.endTransmission();
delay(10);
}

// LCD関係 上段の行にデータ書き込み
void LCD_DISP_16_1(void) {
for (int i = 0; i < 16; i++) {
writeData(stSet[i]);
}
}

// LCD関係 下段の行にデータ書き込み
void LCD_DISP_16_2(void) {
writeCommand(0x40 + 0x80);
for (int i = 0; i < 16; i++) {
writeData(stSet[i]);
}
}

// LCD関係 液晶初期化
void init_LCD()
{
delay(100);
writeCommand(0x38); // FUNCTION SET
delay(20);
writeCommand(0x39); // IS=1
delay(20);
writeCommand(0x14); // INT OSC FREQUENCY
delay(20);
writeCommand(0x7A); // CONTRAST SET 0,1,2,3
delay(20);
writeCommand(0x54); // CONTRAST SET 4,5
delay(20);
writeCommand(0x6C); // F0LLOWER CONTROL
delay(20);
writeCommand(0x38); // IS=0
delay(20);
writeCommand(0x0C); // Display ON
delay(20);
writeCommand(0x01); // Clear Display
delay(20);
writeCommand(0x06); // Entry Mode
delay(20);
}

void loop() {

// カーソルをホームへ戻す
writeCommand(0x02);

// 1行目表示 WORDCOUNTER+a_val値
a_val = (float)analogRead(analogPin) / 1024.0f * 5.0f; //AD変換
//Serial.println(a_val);
dtostrf(num, 1, 1, cNum);
stNum = String(cNum);
dtostrf(a_val, 1, 2, cAval);
sprintf(cCntA, "%d", cntA);
stCntA = String(cCntA);
stAval = String(cAval);
stSet = String(stNum + " " + stAval + "v " + stCntA + "c");
LCD_DISP_16_1();

// 2行目表示 LED音量ボリューム+カウント値+時分秒
d_val = digitalRead(digitalPin);
a_val = analogRead(analogPin);

if (d_val == LOW) {
digitalWrite(led03, LOW);
digitalWrite(led08, LOW);
digitalWrite(led07, LOW);
digitalWrite(led06, LOW);
digitalWrite(led05, LOW);
digitalWrite(led04, LOW);
}
if (d_val == HIGH) {
digitalWrite(led03, HIGH);
}
if (d_val == HIGH && a_val < 500) {
digitalWrite(led03, HIGH);
digitalWrite(led04, HIGH);
LCD_writer();
}
if (d_val == HIGH && a_val < 480) {
digitalWrite(led05, HIGH);
LCD_writer();
}
if (d_val == HIGH && a_val < 460) {
digitalWrite(led06, HIGH);
LCD_writer();
}
if (d_val == HIGH && a_val < 440) {
digitalWrite(led07, HIGH);
LCD_writer();
}
if (d_val == HIGH && a_val < 420) {
digitalWrite(led08, HIGH);
LCD_writer();
}

// リセットボタン
if (digitalRead(buttonBpin13) == LOW) {
LCD_writer();
}

// 文字数変換基準変更ボタン +1
if ((digitalRead(buttonBpin11) == LOW) && (num < 4.9)) {
num = num + 0.1;
tmpA = Wcnt;
cntB = 0;
}

// 文字数変換基準変更ボタン -1
if ((digitalRead(buttonBpin12) == LOW) && (num > 2.1)) {
num = num - 0.1;
tmpA = Wcnt;
cntB = 0;
}
}
// LCD_writer
void LCD_writer() {

// リセットボタン押した
if (digitalRead(buttonBpin13) == LOW) {
cntA = 0;
cntB = 0;
tmpA = 0;
tmpB = 0;
Wcnt = 0;
}
// リセットボタン押してない
if (digitalRead(buttonBpin13) == HIGH){
cntA = cntA + 1; // 総カウント用
cntB = cntB + 1; // 文字数計算用
}

// 時分秒 文字数 計算
sec = (cntB / 16) % 60;
min = ((cntB / 16) % 3600) / 60;
hour = (cntB / 16) / 3600;
tmpB = cntB / num;
Wcnt = tmpA + tmpB;

// LCD表示
sprintf(cSec, "%d", sec);
sprintf(cMin, "%d", min);
sprintf(cHour, "%d", hour);
sprintf(cWcnt, "%d", Wcnt);
stSec = String(cSec);
stMin = String(cMin);
stHour = String(cHour);
stWcnt = String(cWcnt);
stSet = String(stHour + "h" + stMin + "m" + stSec + "s" + " " + stWcnt + "w");
LCD_DISP_16_2();

Serial.println(a_val);
}

 率直に言って、まだ試作品とも呼べない代物です。

 マイクセンサー(KY-037)が音や声を検知している間はデジタル出力がHIGHになり、HIGHになっているあいだカウントが+1され続けます。LCD1行目の右側の値です。

 そのカウント値を基準に、LCD2行目に時間と文字数が表示されます。カウント値が60秒間HIGHだと+100になるので徐算して実時間に合わせています。文字数はLCD1行目左の値を基準にこちらも徐算しています。写真だと「2.5」なので1秒間に「6.4」増える計算です。

 つまり音センサー君の検知頼みなわけですが、この検知の精度が非常に調整しにくい。使い方を解説しているブログをいくつか渡り歩いて調整したんですが、普通の話し声の大きさだと口のすぐ近くにマイクがないと検知しないですし、手を叩いた音を検知させる場合も30cm以内じゃないと厳しいかな。

 少なくとも「話し声を検知させる」という使い方をする上では、相性が良いものだと思えませんでした。

 今の自分の実力だとこれくらいが限界です。

 

 次回をお楽しみに!

タイトルとURLをコピーしました