Arduinoによる放射線データ収集(2)

前回(0)(1)をやったので、今回は(2)LCDに表示、および(3)ethernetシールドでネットに接続について書きます。

スタンドアロンの最低限の実装としては(2)で十分である。
通常のキャラクタLCDでは6ピンのI/Oが必要である。(RS,EN,D4,D5,D6,D7)
ただし、atmega168/328ではピンが限られていることから、他の機能を追加するのであれば、ピンの選択を最初に考えておいた方がよい。
イーサネットシールドを使うと、4,10,11,12,13,14,15が塞がってしまう。
更にGPSを使うとすれば2ピン必要、Xbeeでも2ピン必要であるから、atmega328pではさすがに全部入りは難しい。

アウトドアで使うとすれば、リアルタイムのデータ表示と場所情報の取得と記録または転送があれば十分。

ピンの機能一覧(赤はethernet shieldをつないだ時点で使用済、青はLCDで使用)
D0 RX
D1 TX
D2 INT0
D3 INT1
D4 CS(SDcard)
D5 PWM
D6 PWM
D7 RS
D8 EN
D9 PWM
D10 SS
D11 MOSI
D12 MISO
D13 SCK
D14 A0 WP(SD)
D15 A1 DETECT(SD)
D16 A2 LCD D4
D17 A3 LCD D5
D18 A4 LCD D6
D19 A5 LCD D7

ここではアナログIOを使わないことにして、D16~19(A2~A5)をLCDのD4~D7に割り当て、
D7,D8をRS,ENに割り当てることにします。
(PWMはGM管への高電圧ドライブに使うこともできるので、一つは残しておきたいところ)

実装はライブラリを使えば簡単です。
LiquidCrystalとEthernet
が使えます。

ethernet shieldについては以前https://stastaka.wordpress.com/2010/08/31/ethernet-shield/で書きました。
なお最近出たArduino-1.0betaではDHCPとDNSが実装されていました。

LCDはバックライトなしで動くので
http://akizukidenshi.com/catalog/g/gP-01675/
を使いました。
ピンアサインは

のようになっているので、
LCD – Arduino
1 – GND
2 – VCC
3 – 可変抵抗を通してVCC
4 – D7
5 – GND
6 – D8
7 –
8 –
9 –
10 –
11 – A2
12 – A3
13 – A4
14 – A5
15 –
16 –

とつなぎました。
試しにサーバにしてCPMを表示するだけのコードを書いてみます。

#include <LiquidCrystal.h>
#include <SPI.h>
#include <Ethernet.h>
/*
 SETUP: HD44780 compat LCD
 +5V: LCD Vdd pin 2
 GND: LCD Vss pin 1, R/W pin 5
 LCD RS pin 4 to D7
 LCD EN pin 6 to D8
 LCD D4-D7 pins to A2-A5
 10k pot - ends to +5V and Gnd, wiper to LCD VO pin 3 
 */

#define PERIOD 10000

LiquidCrystal lcd(7, 8, 16, 17, 18, 19);
// ENter a MAC address and IP address for your controller
byte mac[] = { 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
byte ip[] = { 
  192, 168, 1, 99 };

volatile boolean newEvent = false;
unsigned long startTime, startPeriod, samplePeriod;
unsigned long currCnt, CPM, sum;

Server server(80);

void setup()
{
  Serial.begin(9600);
  samplePeriod = PERIOD;

  attachInterrupt(0, GetEvent, FALLING);
  startTime = millis();
  startPeriod = startTime;

  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  lcd.clear();
  lcd.print("Geiger counter start");
  Serial.println("### geiger counter start.");
  Ethernet.begin(mac, ip);
  server.begin();
}

void loop()
{
  if (millis() > startPeriod + samplePeriod) ProcCounts();
  if (newEvent) {
    currCnt++;
    newEvent = false;
  }

  Client client = server.available();
  if (client) {
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        if (c == '\n' && currentLineIsBlank) {
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();

          client.print(CPM);
          client.println(" CPM");
          break;
        }
        if (c == '\n') {
          currentLineIsBlank = true;
        } 
        else if (c != '\r') {
          currentLineIsBlank = false;
        }
      }
    }
    delay(1);
    client.stop();
  }
}

void GetEvent()
{
  newEvent = true;
}

void ProcCounts()
{
  CPM = (currCnt * 60)/(samplePeriod / 1000);
  currCnt = 0;
  startPeriod = millis();
  displayCount();
}

void displayCount()
{
  lcd.setCursor(0, 0);
  lcd.print("CPM ");
  lcd.setCursor(4, 0);
  lcd.print(CPM);
  Serial.print(CPM);
  Serial.println(" CPM");
}

pachubeに登録してデータを発信する方法は
http://www.yapan.org/main/2011/03/measure_radiation_dose.html
に詳しく書かれているので、参照してください。

広告
カテゴリー: Arduino, AVR

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

カテゴリー
2011年6月
« 5月   8月 »
 12345
6789101112
13141516171819
20212223242526
27282930  
%d人のブロガーが「いいね」をつけました。