ネスカフェ バリスタをスマホでコントロール

ネスカフェ バリスタラズベリーパイを接続して、Wifiネットワークからスマホタブレットなどのブラウザーからスイッチをコントロールできるようにしてみた。
とは、言うものの、これまた、先人の知恵の結集なのであります。 ・・・いつまでたってもゼロから自分でできるだけの実力がつかんなぁ~・・・。

ネスカフェ バリスタをスマホでコントロール

あ、スマホでコントロールとか言いながら、動画では、iPad使ってますが、Safariつかうから、結局おんなじですよね。
スマホだったら、Google Chromeでいけます。もちろん、IEでも。
たとえば、インターネットを介してもスイッチのコントロールができるので、遠くはなれたところからもコーヒーを入れたりすることができる。車を駐車場に入れたあたりで、コーヒーを入れておくと、部屋に入ったらすぐにコーヒーが飲めたり、留守中にうちにいる人にコーヒーを入れてあげたり・・・。と、いうシチュエーションがあるかどうかわからないが、なんか、まぁ、スマホでコーヒーが入れれたら、なんか、クールな感じがしない・・・?

以下その詳細
例によって、お約束!
以下の記事を参考にされて、何かされる場合は、すべて、自己責任でお願いしますね。何かが壊れたとか、感電したとか、さまざまなトラブルに見舞われるかもしれませんが、当方は、一切、責任とれませんので、そこんとこ、よろしく・・・。
で、
本当は、バリスタのスイッチのコントロールの通信やプロトコルをハックするのがスマートなんだろうけど、ここは、力まかせに、スイッチから線を引き出してきてフォトカプラでラズベリーパイからスイッチをいれている。フォトカプラでなくても、リレーとかでも同じだと思いますが、リレーの場合は、ラズパイから直接駆動するほど電流流せないので、別途、トランジスタを使って、電源から駆動しないといけないかと思うので、フォトカプラが簡単かと思います。
回路図を描くほどでもないけど、しいて描けば、こんな感じ。
f:id:manpukukoji:20160214223150j:plain
フォトカプラにつなぐ抵抗の値は、だいたい、200Ωくらいから、1kΩくらいでいけると思う。
f:id:manpukukoji:20160217203757j:plain

バリスタのスイッチのコントロールに加えて、音声合成ICで発声させているのでこちらのハードも作成しなければならない。
これは、以前に作成したものを流用している。
blog.goo.ne.jp
このときは、リモコンで発声する言葉をコントロールしていたが、この基板からPIC12F629を引っこ抜いて、出力PINのところにラズパイのGPIOの出力を接続してコントロールしている。 データーはあらかじめプリセットのメッセージを作っておいてラズパイの出力でメッセージを選択、発声させています。
AquesTalkのメッセージのビット0,1,2の順にそれぞれ、ラズパイのGPIOの24,25,10を使っています。

ハードは、以上で、あとは、ラズパイ側のソフトの準備
Webを通して、GPIOをコントロールするのには、WebIOPiというソフトを使っています。
基本的には、ラズパイマガジンの2015年春号を参考にした(P.56 WebIOPiをカスタマイズしよう)ので、それとほぼ同じ構成になっています。
まず、WebIOPiのインストール 私がインストールしたときは、バージョンが0.7.1 でした。
WebIOPiのインストールに関しても、詳しく説明してくれているサイトがたくさんあるので、問題ないと思うけどまぁ、ざっくりと・・・。

$ wget http://sourceforge.net/projects/webiopi/files/WebIOPi-0.7.1.tor.gz/download
$ tar xvzf WebIOPi-0.7.1.tar.gz

これで、WebIOPiが展開されているはずだが、このままでは、ラズパイ2では、使えないようで、
少しファイルを編集する必要がある。
/WebIOPi-0.7.1/python/native/cpuinfo.c というファイルの40行目あたり
if(strcmp(hardware,"BCM2708")==0) という行の2708を2709に変更
それと、もう一つ
/WebIOPi-0.7.1/python/native/gpio.c というファイルの32行目あたり
#define BCM2708_PERI_BASE 0x20000000 と、いう行の0x20000000を0x3f000000に変更

変更したらインストール

~/WebIOPi-0.7.1$ sudo setup.sh

インストールしたら、次にコントロールのためのWebサイトを作成する。
webiopi_site というディレクトリを作成し、その下にさらに"htdocs" というディレクトリと"script"というディレクトリを作成。
htdocsにsample03.html と sample.css と sample03.js という3つのファイルをエディタで作成。(短いので、コピペしてね)

$ mkdir webiopi_site
$ cd webiopi_site
$ mkdir htdocs
$ mkdir script
$ cd htdocs
$ nano sample03.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.o$
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <title>01 | WebIOPi-Barista control</title>
  <script type="text/javascript" src="/webiopi.js"></script>
  <script type="text/javascript" src="./sample03.js"></script>
  <link rel="stylesheet" type="text/css" href="./sample.css">
</head>
<body>
  <div id="content"></div>
</body>
</html>
$nano sample.css
button {
  display: block;
  margin: 2px;
  width: 200px;
  height: 45px;
  font-size: 16pt;
  font-weight: bold;
  color: Black;
}
input[type="range"] {
  display: block;
  width: 200px;
  height: 45px;
}
.LOW {
  color: LightGray;
  background-color: Gray;
}
.HIGH {
  color: White;
  background-color: Red;
}
$ nano sample03.js
webiopi().ready(function() {
  var content, button;
  content = $("#content");
  button = webiopi().createMacroButton("btn_power","◎","PowerOn");
  content.append(button);
  button = webiopi().createMacroButton("btn_black", "Black(Cup)","CupOn");
  content.append(button);
  button = webiopi().createMacroButton("btn_Mag", "Mug Cup","MagOn");
  content.append(button);
  button = webiopi().createMacroButton("btn_esp", "Espresso","EspOn");
  content.append(button);
  button = webiopi().createMacroButton("btn_late", "Latte","LateOn");
  content.append(button);
  button = webiopi().createMacroButton("btn_cuppcino", "Cappuccino","CappOn");
  content.append(button);

  webiopi().refreshGPIO(true);
});

次に、script のディレクトリでPythonのマクロを作成

$ cd ../script
$ nano Sample02.py
import webiopi

GPIO = webiopi.GPIO
STRT = 8
CUP = 17
MAG = 18
ESP = 27
CAPP = 22
LATE = 23
P0 = 24
P1 = 25
P2 = 10

def setup():
        GPIO.setFunction(STRT,GPIO.OUT)
        GPIO.setFunction(CUP,GPIO.OUT)
        GPIO.setFunction(MAG,GPIO.OUT)
        GPIO.setFunction(ESP,GPIO.OUT)
        GPIO.setFunction(CAPP,GPIO.OUT)
        GPIO.setFunction(LATE,GPIO.OUT)
        GPIO.setFunction(P0,GPIO.OUT)
        GPIO.setFunction(P1,GPIO.OUT)
        GPIO.setFunction(P2,GPIO.OUT)

        GPIO.digitalWrite(STRT,GPIO.LOW)
        GPIO.digitalWrite(CUP,GPIO.LOW)
        GPIO.digitalWrite(MAG,GPIO.LOW)
        GPIO.digitalWrite(ESP,GPIO.LOW)
        GPIO.digitalWrite(CAPP,GPIO.LOW)
        GPIO.digitalWrite(LATE,GPIO.LOW)
        GPIO.digitalWrite(P0,GPIO.HIGH)
        GPIO.digitalWrite(P1,GPIO.HIGH)
        GPIO.digitalWrite(P2,GPIO.HIGH)

@webiopi.macro
def PowerOn():
        GPIO.digitalWrite(STRT,GPIO.HIGH)
        GPIO.digitalWrite(P0,GPIO.LOW)
        GPIO.digitalWrite(P1,GPIO.LOW)
        GPIO.digitalWrite(P2,GPIO.LOW)
        webiopi.sleep(1)
        GPIO.digitalWrite(STRT,GPIO.LOW)
        GPIO.digitalWrite(P0,GPIO.HIGH)
        GPIO.digitalWrite(P1,GPIO.HIGH)
        GPIO.digitalWrite(P2,GPIO.HIGH)

@webiopi.macro
def CupOn():
        GPIO.digitalWrite(CUP,GPIO.HIGH)
        GPIO.digitalWrite(P1,GPIO.LOW)
        GPIO.digitalWrite(P2,GPIO.LOW)
        webiopi.sleep(1)
        GPIO.digitalWrite(CUP,GPIO.LOW)
        GPIO.digitalWrite(P1,GPIO.HIGH)
        GPIO.digitalWrite(P2,GPIO.HIGH)

@webiopi.macro
def MagOn():
        GPIO.digitalWrite(MAG,GPIO.HIGH)
        GPIO.digitalWrite(P0,GPIO.LOW)
        GPIO.digitalWrite(P2,GPIO.LOW)
        webiopi.sleep(1)
        GPIO.digitalWrite(MAG,GPIO.LOW)
        GPIO.digitalWrite(P0,GPIO.HIGH)
        GPIO.digitalWrite(P2,GPIO.HIGH)

@webiopi.macro
def EspOn():
        GPIO.digitalWrite(ESP,GPIO.HIGH)
        GPIO.digitalWrite(P2,GPIO.LOW)
        webiopi.sleep(1)
        GPIO.digitalWrite(ESP,GPIO.LOW)
        GPIO.digitalWrite(P2,GPIO.HIGH)

@webiopi.macro
def CappOn():
        GPIO.digitalWrite(CAPP,GPIO.HIGH)
        GPIO.digitalWrite(P0,GPIO.LOW)
        GPIO.digitalWrite(P1,GPIO.LOW)
        webiopi.sleep(1)
        GPIO.digitalWrite(CAPP,GPIO.LOW)
        GPIO.digitalWrite(P0,GPIO.HIGH)
        GPIO.digitalWrite(P1,GPIO.HIGH)

@webiopi.macro
def LateOn():
        GPIO.digitalWrite(LATE,GPIO.HIGH)
        GPIO.digitalWrite(P1,GPIO.LOW)
        webiopi.sleep(1)
        GPIO.digitalWrite(LATE,GPIO.LOW)
        GPIO.digitalWrite(P1,GPIO.HIGH)

@webiopi.macro
def led1():
        GPIO.digitalWrite(LED,GPIO.HIGH)
        webiopi.sleep(1)
        GPIO.digitalWrite(LED,GPIO.LOW)
        webiopi.sleep(1)
        GPIO.digitalWrite(LED,GPIO.HIGH)
        webiopi.sleep(1)
        GPIO.digitalWrite(LED,GPIO.LOW)
        webiopi.sleep(1)

def destroy():
        GPIO.digitalWrite(STRT,GPIO.LOW)
        GPIO.digitalWrite(CUP,GPIO.LOW)
        GPIO.digitalWrite(MAG,GPIO.LOW)
        GPIO.digitalWrite(ESP,GPIO.LOW)
        GPIO.digitalWrite(CAPP,GPIO.LOW)
        GPIO.digitalWrite(LATE,GPIO.LOW)
        GPIO.digitalWrite(LED,GPIO.LOW)

これで、だいたい準備完了 (プログラムが長くなっちゃった。 ちょっと、書き方を考えないと・・・。)
あとは、以下のように、WebIOPiのドキュメントルートを指定して、サーバー用スクリプトファイルを指定

$ cd /etc/webiopi/
$ nano config

[SCRIPTS] のセクションのおしまいのところに、
myscript = /home/pi/webiopi_site/script/Sample02.py

[HTTP}のセクションで
#doc-root = /home/pi/webiopi/examples/scripts/macros の下に
doc-root = /home/pi/webiopi_site/htdocs

と記入し、保存
これで、準備はできたので、WebIOPiをスタートして、スマホのブラウザから同じネットワークに接続して、上記で作成した、ラズパイのWebIOPiのサイトにアクセスすれば良い。

$ cd ~
$ sudo /etc/init.d/webiopi start

スマホのブラウザからアクセス
例えば、ラズパイのIPアドレスが 192.168.1.10 だったとすると、

http://192.168.1.10:8000/sample03.html

へアクセスすれば良い。 ・・・はず、・・・。

これで、うまくいっていれば、自動起動の設定をしておけば、ラズパイのスイッチを入れれば、立ち上げと同時にWebIOPi が起動するようになる。

$ sudo update -rc.d webiopi defaults

自動起動を解除するときは、

$ sudo update -rc.d webiopi remove

とやれば、良いようだ。

それでは、Good Luck!

ネスカフェ バリスタでコーヒーをいれるとツイッターに自動投稿

ネスカフェ バリスタラズベリーパイを接続して、コーヒーを入れると、自動的にツイッターに投稿されるようにしてみた。

実際の映像は、こちらから。(片手でビデオとりながらやっているので、ちょっと、かったるいけどね・・・。)

ネスカフェ・バリスタとラズパイでツイッターに自動投稿


技術的には、何もわかっていなくても、ほとんど先人の知恵でできてしまった。

ネットの知識は、やはり、すごい・・・。

以下、作成までの記録。

自分のための備忘録的なものですが、これ見て、自分もやってみようというかたは、くれぐれも、自己責任でお願いします。 バリスタは、100V電源つながっていますし、熱湯もでるし、間違えると、バリスタ壊したり、ラズパイ壊したりして、痛い出費になってしまいますので・・・。 当方は、責任取れませんので、あしからず・・・。

準備、

まず、ネスカフェ バリスタのサイドパネルをはずす。

バリスタは、すでに何度かモデルチェンジしているので、同じようには行かないかもしれません。私が使ったのは、初代のモデルです。型番でいくとPM9630だと思うのですが、同じ9630でも、初期のものと、後のものではボタンの位置とか少し異なっているようです。基板もかわっているのかもしれません。

サイドパネルのはずし方は、こちらのサイトが写真入りで詳しく解説されているので参考になります。

ネスカフェ バリスタの調子が悪いので分解清掃してみた | KUMA TYPE

ネジはトルクスねじが使われているので、専用ドライバが必要です。まぁ、通常のプラスドライバとかマイナスドライバを駆使して回しちゃう"つわもの"もいるでしょうけど・・・。

とりあえず、コーヒーパウダーのタンク下の4本のネジをはずすだけで用は足りると思います。上記の参考サイトにも書かれていますが、サイドパネルをはずすときには、かなりの確率で爪が折れます。 私の場合も4本中3本折れちゃいました。それなりの覚悟が必要かと・・・。

この4本のネジをはずすとポコッと頭の部分が外れます。 この頭の中にスイッチの基板が埋まっているので、内側からつめを押さえて外に向かって押し込んでやると、外側にスイッチパネルが外れると思います。

f:id:manpukukoji:20160212205822j:plain

スイッチパネルが外れたら、基板の真ん中にあるスタート/停止のスイッチから線を半田付けして引き出してきます。引っ張り出すのは、電圧の高い側で、私の場合、4.9Vくらいありました。低い側は、ほぼ、0V、実際には、100mV くらいありました。写真の矢印のところ

f:id:manpukukoji:20160212210034j:plain

このラインをラズベリーパイのGPIOピンのひとつにつなぐわけですが、前述のようにバリスタは、5VでラズベリーパイのI/Oは、3.3Vなので、このままつなぐと、ラズパイが壊れてしまいますので、何か方法を考えます。

やり方は、いくつか考えられますが、入力ひとつだけなので、ちゃんとした電圧変換モジュールを使うところまでしなくとも、抵抗で分圧したり、トランジスタとかFETをひとつ、かませたり、ダイオードで電圧を落としたり、どの方法でも良いと思います。

"5V 3V 信号変換 " といったワードで検索すると、さまざまなやり方が見つかると思います。

私の場合は、手っ取り早くLEDと100kの抵抗を直列にかまして落としちゃいました。

このやり方は、正当なやり方ではないかと思いますが、電源ラインやGNDラインに落とさなくても良いので、接続先が増えなくて都合が良かったという理由です。

LEDは、Vfが2V くらいあれば良いと思います。ただし、光りません・・・。

とりあえず、これで、ラズパイが壊れることもなく、使えています。
私の場合、バリスタからの入力をGPIO23(Pin#16)に、LEDへの出力をGPIO24 (Pin#18)に接続しています。

あとは、GND側をラズパイのGNDとつなげば、ハードの方はOKです。

GNDは、本体側にそれっぽいピンが出ていたので、これを使いました。

f:id:manpukukoji:20160213080025j:plain

これで、ハード側は、おしまいですが、おまけでスイッチが入ったときにLEDが点滅するようにブレッドボード上に組んでみました。

ちなみに、バリスタのスタート/停止スイッチが入っていないときは、ラズパイのGPIOは、Highとなっていて、スイッチが入ったときにLowになりますので、そこで、スイッチが入ったことを検知します。

次に、ラズベリーパイにOSのインストール

これは、もう、山のように参考サイトがあるので、そちらで十分かと思いますが、今回、はまったのは、NOOBS v1.4.1をインストールしたときは、何もしないで日本語で表示されたのだけど、v1.5.0をインストールしたら、日本語が文字化けしてしまった。

いろいろ、調べてみたら、[$ sudo apt-get install fonts-vlgothic ] と、やったら、文字化けが解消されました。

次にPythonでツイートするための準備で、twython と、いうのを使います。

このあたりは、こちらのサイトを参考にさせてもらいました。

Raspberry PiのCPU温度をつぶやくTwitterBot | そう いう わけさ

上記参考サイトに習って、TwitterBotの環境を作成

$ mkdir TwitterBot
$ cd TwitterBot

twuthonをインストールして、Twitterのアカウントをとったら、Pythonのプログラムを作成。 これも、参考サイトのスクリプトを少し変更するだけでできてしまう。

以下のような感じで・・・。

 $ nano RaspiBot.py 
#!/usr/bin/env python
# coding: utf-8
import RPi.GPIO as GPIO
import time
import os
from twython import Twython
import datetime

COUNT = 3
LED = 24
Brst_SW = 23
GPIO.setmode(GPIO.BCM)
GPIO.setup(LED,GPIO.OUT)
GPIO.setup(Brst_SW,GPIO.IN)
GPIO.output(LED,False)

def LCHIKA():
	global COUNT
	global LED
	for _ in xrange(COUNT):
		GPIO.output(LED,True)
		time.sleep(1.0)
		GPIO.output(LED,False)
		time.sleep(1.0)

def Tweet():
	#Twitterの認可情報を入力	
CONSUMER_KEY = 'XXXXXXXXXXXXXXXXXXXXXXXXX'
	CONSUMER_SECRET = 'XXXXXXXXXXXXXXXXXXXXXXXXXX'
	ACCESS_KEY = '1234567890-XXXXXXXXXXXXXXXXXXXXXXX'
	ACCESS_SECRET = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
	api = Twython(CONSUMER_KEY,CONSUMER_SECRET,ACCESS_KEY,ACCESS_SECRET)

	timestamp = 'date +%F_%H:%M:%S'
	current_time = os.popen(timestamp).readline().strip()

	api.update_status(status=current_time+' : コーヒーでくつろぎ中!!')

try:
	while True:
		if (GPIO.input(Brst_SW) == 0):
			Tweet()
			LCHIKA()
except(KeyboardInterrupt):
	print('KeyboardInterrupt!')

GPIO.cleanup()

実行権限を付与

$ chmod +x RaspiBot.py

これでほぼ完成。
あとは、

$ RaspiBot.py

と、やって実行し、バリスタでコーヒーを入れて、コーヒー飲みながらツイッターの再読み込みすると、ツイートされている・・・はず・・・。


ブログ再開

以前、書いていたブログにアクセスできなくなってしまい、何年かほったらかしにしていたけど、久しぶりにお引越しをして再開することにした。

以前のブログは、セキュリティに問題が発生したとかで、ほぼ、強制的にパスワードを変更させられたのだが、変更後のパスワードを記録していなかったので、わからなくなってしまい、なんか、キーワードみたいなのもわからず、お手上げ状態。

もう、そのまま、削除されるまで放っておくしかしかたなくなってしまった。

ちなみに、サイトは、まだ、生きているので興味のある方は、こちらから・・・。

 

 

blog.goo.ne.jp