プッシュスイッチを押すとメールを送信する
作成 : 2013/01/14
プッシュスイッチを押すとメールを送信する
Arduino UnoとEthernet Shieldを組み合わせてSMTPクライアントにします。 デジタルピン#7にプッシュスイッチを接続し、ボタンを押した時にメールを送信します。 サーバからのレスポンスを読み取っていますが、解析する処理は省略しています。
接続先は、自宅にあるSMTPサーバ(192.168.1.10)です。 ISP等外部のSMTPサーバを指定するのは、予期しない動作をしたときにご迷惑なので避けました。
/*********************
デジタルピン#7に接続されたプッシュスイッチをオンにしたとき、SMTPサーバに接続してメールを送信する。
Arduino Uno
http://www.arduino.cc/en/Main/arduinoBoardUno
Arduino Ethernet Shield
http://arduino.cc/en/Main/ArduinoEthernetShield
**********************/
#include <SPI.h>
#include <Ethernet.h>
// Arduino Ethernet ShieldのMACアドレス
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0x99, 0x50 };
// Arduinoに設定するTCP/IP情報
byte ip[] = { 192, 168, 1, 200 };
byte gateway[] = { 192, 168, 1, 1 };
byte subnet[] = { 255, 255, 255, 0 };
// 接続するサーバのIPアドレス
IPAddress server(192, 168, 1, 10);
EthernetClient client;
// プッシュスイッチを接続するポートを定義
#define inPin 7
// サーバからの受信するレスポンスの最大文字数を定義
#define MSGBUF 1024
// 最初に1回だけ実行
void setup() {
// デジタルピン#7を入力に設定
pinMode(inPin, INPUT);
// シリアル通信の転送レートを設定
Serial.begin(9600);
// ネットワーク設定を初期化
Ethernet.begin(mac, ip, gateway, subnet);
}
// 繰り返し実行
void loop() {
// サーバから受信したレスポンスを格納する変数
char rcvMsg[MSGBUF];
Serial.println(digitalRead(inPin));
// デジタルピン#7が'HIGH'だったら
if (digitalRead(inPin) == HIGH) {
// SMTPサーバに接続
client.connect(server, 25);
Serial.println("connect server");
// SMTPサーバに接続したらtrue
if (client.connected()) {
// 以下、sendCmd関数を呼んでサーバにコマンドを発行し、レスポンスをrcvMsgに格納
// 最初のコマンドが""なのは、サーバに接続したときのレスポンスを読み取るため
sendCmd ("", rcvMsg);
sendCmd ("EHLO nina.jp", rcvMsg);
sendCmd ("MAIL FROM:foo@nina.jp", rcvMsg);
sendCmd ("RCPT TO:bar@nina.jp", rcvMsg);
sendCmd ("DATA", rcvMsg);
sendCmd ("Subject: TEST MAIL\r\ntest mail\r\n.", rcvMsg);
sendCmd ("QUIT", rcvMsg);
delay(1);
// サーバから切断
client.stop();
Serial.println("disconnect server");
}
}
// 1秒待つ
delay(1000);
}
// サーバにコマンドを発行して、レスポンスを受信する
// 戻り値はレスポンスの文字長
// char* sendStr : サーバに発行するコマンドを格納、char* rcvStr サーバからのレスポンスを格納
long sendCmd(char* sendStr, char* rcvStr) {
long idx=0;
// サーバに発行するコマンドがあるときは、サーバにコマンドを送信
// 発行するコマンドがないとき、サーバからのレスポンス(バナーとかプロンプトとか)があれば受信
if(sendStr != "") {
client.println(sendStr);
}
Serial.print("send command: "); Serial.println(sendStr);
// コマンド送信して、レスポンスを受信するまでの時間を調整
// delayをいれないと、次のclient.available()がfalseになってしまったのです
delay(10);
// サーバから受信するレスポンスがある間はtrue
while (client.available()) {
// サーバからのレスポンスを読み取る
char c = client.read();
// レスポンスをrcvStrに格納する
// レスポンスが規定最大サイズMSGBUF-1(-1は'\0'付加を考慮した分)を超える場合は、データを破棄
if (idx < MSGBUF - 1) {
rcvStr[idx] = c;
idx++;
}
}
// rcvStrに格納した文字列の後ろにNULLを追加して、文字列の終わりを示す
rcvStr[idx] = '\0';
Serial.print("receive message: "); Serial.println(rcvStr);
// 関数の戻り値として、レスポンスの文字長を返す
return strlen(rcvStr);
}
シリアル出力結果は以下のようになりました。
0 0 0 1 connect server send command: receive message: 220 linux.nina.jp ESMTP Sendmail 8.14.5/8.14.4; Mon, 14 Jan 2013 15:54:24 +0900 send command: EHLO nina.jp receive message: 250-linux.nina.jp Hello [192.168.1.200], pleased to meet you 250-ENHANCEDSTATUSCODES 250-PIPELINING 250-8BITMIME 250-SIZE 250-DSN 250-ETRN 250-AUTH DIGEST-MD5 CRAM-MD5 250-STARTTLS 250-DELIVERBY 250 HELP send command: MAIL FROM:foo@nina.jp receive message: 250 2.1.0 foo@nina.jp... Sender ok send command: RCPT TO:bar@nina.jp receive message: 250 2.1.5 bar@nina.jp... Recipient ok send command: DATA receive message: 354 Enter mail, end with "." on a line by itself send command: Subject: TEST MAIL test mail . receive message: 250 2.0.0 r0E6sO9P002591 Message accepted for delivery send command: QUIT receive message: 221 2.0.0 linux.nina.jp closing connection disconnect server 0 0 0