ぼくがTransBook T90Chiを購入した理由

お久しぶりです、ぺんたです。

先日、NTT-XストアでASUSの8.9型2in1ノートであるTransBookT90Chiを購入しました。

使っていて1週間ほど経ったので選んだ理由、良い点、悪い点を挙げて私の期待に答えられる製品だったかを考えてみます。

なぜTransBook T90Chiを買ったか

私はモバイルノートPCが好きで昔から憧れていました。
今まで主にモバイル用途で使っていたノートPCはLet's note R9、Le'ts note S10でした。さらに遡るとネタで中古のLibretto70やmobioなどを持っていたこともあります(もっとも、ほとんどバッテリーが持たなくて使い物になりませんでしたが)

私が高専生だったころは授業や実験で使用したり、ロボコンでプログラムや回路を書いていたので堅牢でバッテリーがよく持つモバイルノートであることが必須条件だったのでレッツノートを選んでいました。

しかし、社会人となり、田舎暮らしとなった今は仕事では会社のPCを使いますし通勤時間も短いので外でノートPCを使う機会がぐっと減りました。

現在稼働できるモバイルノートはMacBookAir2015とLet's note S10があります。
タブレットも含めるとiPad mini retinaも持っています。

なぜそんな私がTransBook T90Chiを買ったかというと

  1. 小さいモバイルノート昔からの憧れであった
  2. Windowsである
  3. 2万円弱と、かなり安く気軽に持ち歩ける値段であった

主にこの3点です。

先述したように小さいモバイルノートは昔からの憧れで、何機種も中古ノートを買ってきました。このTransBookb T90ChiはWindows10タブレットながらBltuetoothキーボードが標準でついており、きちんとヒンジが付いているためノートPCスタイルで使用することができます。
また、OSはWindows10なのでWebページがPCと同様にみれる他、ネイティブでFlashなどにも対応しています。普段PCで使っているアプリケーションが動作するというのは非常に大きいことです。
最後に、このTransBookT90Chiがとても安価になっているということが最終的に購入に至った理由です。モバイル機器は外に持ち歩くので破損や盗難の恐れが非常に高いです。十数万円もするモバイル機器では気を使ってしまいます。しかし、2万円弱という値段なら壊れても、盗難にあってもそこまで痛手ではありません。

というわけで私は深夜のテンションと値段につられてNTT-XストアでTransBook T90Chiをポチってしまいました。

TransBook T90Chiのいい点

小さい

やはり本体がとても小さいのでどんなところでも気軽に開いて作業ができることです。
喫茶店やマックなどの小さいテーブルの上でも置けます。しかも重心はディスプレイ側にあるので、キーボードは多少テーブルからはみ出ていても問題ありません(少し打ちにくいですが)。

スピーカー

この手のタブレットに音質は全く期待していなかったのですが、音量、音質ともに悪くないです。低音は皆無と言っていいほど出ないですが、中音域はよく出るので人の声なんかは非常にクリアで聞き取りやすいです。
ノベルゲーなどをやろうと考えている方なんかには非常にいいポイントだと思います。

キーボードの打鍵感

この2in1ノートPCの存在意義であるキーボードですが、流石に本体サイズが小さいものですから、間隔は狭いです。しかし、押し心地はかなりクリック感がありとても気に入っています。キー配列もそこまで苦しくないですし、レッツノートの変則配列よりいいです。
細かい点としては2分ほどでキーボードが省電力モードになるようで、1文字目の反応が遅れます。これは省電力のためには仕方ないですし、1文字目の遅延も遅くても2秒ほどなので特に大きなストレスは感じていません。

TransBook T90Chiのよくない点

ヒンジ、キーボードの剛性がない

キーボードの打鍵感は好きだと書きましたが、キーボード面を持った時の剛性の無さは最悪です。タブレット側は筐体はアルミで出来ていますが、キーボード側はプラスチックで出来ているので剛性はありあせん。
いつもノートPCはキーボード側を持って運ぶ癖があるのですが、2in1のノートPCではやらないほうがいいでしょう。

キーボードの装着感が微妙

キーボードとタブレットの着脱部分はマグネットで保持する機構となっているのですが、この装着感が微妙です。キーボード側の装着面にはタブレット側が傷付かないようにフェルト生地のようなものが貼られているのですが、そのせいで少し磁石の強度が弱まっているのと、iPadのスマートカバーのように強力な磁石でないため、うまく左右の位置が決まりません。これが非常に厄介で、固定できていると思ってもうまくくっついていないことが結構ありました。
解決法としては装着するときは一旦閉じてキーボードの左右位置と合わせれば位置は決まります。

ディスプレイのカメラ付近が浮いてる

この機種の設計上の問題だと思われるのですが、ディスプレイの左上(カメラのあたり)が若干浮いています。押すと少し奥へ動くような間隔があります。気にしない人は気にしないとは思いますが、私は少し気になりました。製品としていささか問題なのではと思います。

その他

まず、Windowsであることが購入理由だと言いましたが、Windows10ならではの不親切設計が散見されます。特にWidows10を初めて買う方は戸惑うような気がしました。製品を買ってからのセットアップ諸々がiPadなどと比べてたら雲泥の差で酷いです。
あとは分かりきっていたことですが、ディスプレイの解像度が低いです。持っているLet's note S10とほとんど変わらない解像度だから気にならないだろうと思っていたの、確かにWindwosノートとしては不足のない解像度なのですが、タブレットとしては不満があります。昨今のスマホタブレットは高解像度化が進んでいて、目がそれに慣れてしまっているのでどうしてもTransBook T90Chiの解像度が低く感じてしまいました。

最後に、最近のAtomは性能が上がっているとは言え、たくさんタブを開いてブラウジングをしたりすると相当イライラします。

総括

ここまでつらつらと書いていきましたが、性能、品質、価格のバランスが取れている非常にいいモバイルノートPCであり、タブレットだと思います。概ね満足しています。AtomのWindows10タブレットはこの程度か、とか思うことも結構ありますが…。
ということで現在値段が下がっていて非常におすすめな2in1ノートPCなので気になっている方はすぐにでも買いましょう。
では最後に、なんで久しぶりに投稿した記事がこんな内容なのかって?物欲のままに気になる機種をポチって使い道が見つからなかったので自分を後悔させないように泣きながら書いたから決まっているじゃないか。

Raspberry PiとBME280でXivelyにデータを送信するガジェットをつくる

最近BME280という湿度、気圧、温度複合センサモジュールが電子部品店で販売されるようになりました。

http://akizukidenshi.com/catalog/g/gK-09421/

  • スイッチサイエンス

https://www.switch-science.com/catalog/2236/

https://strawberry-linux.com/catalog/items?code=12280/


これ1つで湿度、気圧、温度をI2C/SPIで取得することができるので便利そうです。
今回はこのセンサーの値をRaspberry Pi A+上のPythonで取得し、IoT向けサービスであるXivelyにデータを送信するところまで行いました。

使用したハードウェア、ソフトウェア

  1. Raspberry Pi A+
  2. WiFiドングル(LAN-W150N/U2)
  3. BME280使用 温湿度・気圧センサモジュールキット: センサ一般 秋月電子通商 電子部品 ネット通販
  4. Raspbian 2015-05-15
  5. Python 2.7.3

BME280とRaspberry Piの接続

図のように接続します。
I2Cを使用し、オンボードの抵抗を使うのでJ1、J2、J3は全てショートしてください。
f:id:penta_twi:20150701230442p:plain

I2Cの有効化

RaspbianのデフォルトではI2Cは無効化されているのでこれを有効化します。
次の記事を参考にI2Cを有効化しました。
Raspberry Pi の I2C を有効化する方法 (2015年版) - 意識低い開発者のBlog
記事の通りに設定を行ったら

sudo apt-get i2c-tools

を入力します。

各種Pythonライブラリのインストール

smbusモジュールのインストール
PythonでI2Cを使用するためにはsmbusモジュールが必要です。
次のコマンドでインストールします。

$ sudo apt-get install python-smbus

requestsモジュールのインストール

Xivelyにデータを送信する部分はこの記事を参考に書きました。yamaryu0508.hatenablog.com
この記事ではHTTPリクエストにPythonのrequestsモジュールを使用しているのでこちらをインストールします。
また、最新のrequestsモジュールを使用するとInsecurePlatformWarningが出るのでrequests2.5.3を使用しました。

sudo apt-get install python-pip
sudo pip install requests==2.5.3

Xivelyへ登録、チャンネルの作成

Xivelyは個人向けサービスと法人向けサービスに分けられ、個人向けサービスはPersonal Xivelyへと変更されたようです。
登録はここから行います。
Sign Up - Xively

登録の方法とチャンネルの作成などは次の記事を参考に行いました。
この夏,チャレンジ!中学生でも開発可能なM2Mシステム Part3 ―― 3G通信モジュールとクラウド・システムの連携[応用編]|Tech Village (テックビレッジ) / CQ出版株式会社

デバイスRapberry Piに対してチャンネル

  • Temperature
  • Humidity
  • Pressure-Altitude_600m
  • Pressure-Aititude_0m

を作成しました。

Pythonスクリプトの作成

いよいよPythonスクリプトを作成します。
BME280は生のデータから計算して湿度と気圧を算出する必要があります。
データシートや解説を読んでもなんのこっちゃという感じなのでmbedのライブラリのコードを拝借しPython用に書き換えました。雪だるま大先生に感謝です。
BME280 - a mercurial repository | mbed

APY_KEYとFEED_IDは自分のXivelyのチャンネルのものに書き換えてください。
ALTITUDEは実験している場所の高度をメートルで書き換えてください
registToXivelyの第1引数はチャンネル名を指定するのでここも適宜書き換えてください。
今回初めてPythonを使ったのでご了承ください。直した方がいい点などあればご指摘お願いします。

大気圧がPressure-Altitude_0mとPressure-Altitude_600mに分けられている理由は気象庁のデータは海面更正というものを行っていて取得地点の高度のデータを0mの高度のデータに換算しているため、気象庁のデータと比較したい場合にはこの海面更正をする必要があります。
詳しくは気象観測の手引き(pp.37-39)をお読みください。

#!/usr/bin/python

import sys,time
import smbus
import urllib2, json, requests

INTERVAL = 60*0.5 # second

API_KEY = "YOUR API KEY"
FEED_ID = "YOUR FEED ID"

ALTITUDE= 600

class Xively:
	def __init__(self,feedId,apiKey):
		self.feedId = feedId
		self.apiKey = apiKey
	def registToXively(self,channel,dataPoints):
		request = { 'datastreams' : [ {'id' : channel, 'current_value' : dataPoints}]}
		requestJson = json.dumps(request)
		url = "https://api.xively.com/v2/feeds/" + self.feedId + ".json"
		headers = {"X-ApiKey": self.apiKey}
		res = requests.put(url, headers=headers, data=requestJson)
		return res

xivelyDevice = Xively(FEED_ID,API_KEY)

class BME280:
	DEVICE_ADDRESS = 0x76
	BUS_CHANNEL = 1

	def __init__(self,address = DEVICE_ADDRESS,channel = BUS_CHANNEL):
		self.address = address
		self.channel = channel

		self.bus = smbus.SMBus(self.channel)
		self.t_fine = 0

		data = self.bus.read_byte_data(self.address,0xD0)
		# print 'ID:0x%x' % data

		#cfrl hum Humidity oversampling x1
		self.bus.write_byte_data(self.address,0xF2,0x01)

		#ctrl meas  Temparature oversampling x1, Pressure oversampling x1, Normal mode
		self.bus.write_byte_data(self.address,0xF4,0x27)

		#config Standby 1000ms ,Filter off
		self.bus.write_byte_data(self.address,0xF5,0xA0)

		data = self.bus.read_i2c_block_data(self.address,0x88,6)

		self.dig_T1 = (data[1] << 8) | data[0]
		self.dig_T2 = (data[3] << 8) | data[2]
		self.dig_T3 = (data[5] << 8) | data[4]

		data = self.bus.read_i2c_block_data(self.address,0x8E,18)

		self.dig_P1 = (data[ 1] << 8) | data[ 0]
		self.dig_P2 = (data[ 3] << 8) | data[ 2]
		self.dig_P3 = (data[ 5] << 8) | data[ 4]
		self.dig_P4 = (data[ 7] << 8) | data[ 6]
		self.dig_P5 = (data[ 9] << 8) | data[ 8]
		self.dig_P6 = (data[11] << 8) | data[10]
		self.dig_P7 = (data[13] << 8) | data[12]
		self.dig_P8 = (data[15] << 8) | data[14]
		self.dig_P9 = (data[17] << 8) | data[16]


		data[0] = self.bus.read_byte_data(self.address,0xA1) #read dig_H regs

		self.dig_H1 = data[0]

		data = self.bus.read_i2c_block_data(self.address,0xE1,7)

		self.dig_H2 = (data[1] << 8) | data[0]
		self.dig_H3 = data[2]
		self.dig_H4 = (data[3] << 4) | (data[4] & 0x0f)
		self.dig_H5 = (data[5] << 4) | ((data[4]>>4) & 0x0f)
		self.dig_H6 = data[6]


	def getTemperature(self):
		temp_xlsb = self.bus.read_byte_data(self.address,0xFC)
		# print '0x%x' % temp_xlsb

		temp_lsb = self.bus.read_byte_data(self.address,0xFB)
		# print '0x%x' % temp_lsb

		temp_msb = self.bus.read_byte_data(self.address,0xFA)
		# print '0x%x' % temp_msb

		temp_raw = (temp_msb << 12) | (temp_lsb << 4) | (temp_xlsb >> 4)

		temp_data = (((((temp_raw >> 3) - (self.dig_T1 << 1))) * self.dig_T2) >> 11) +\
			 ((((((temp_raw >> 4) - self.dig_T1) * ((temp_raw >> 4) - self.dig_T1)) >> 12) * self.dig_T3) >> 14)

		self.t_fine = temp_data
		temp_data = (temp_data * 5 + 128) >> 8
		return temp_data / 100.0


	def getPressure(self):
		data = self.bus.read_i2c_block_data(self.address,0xF7,3)
		press_raw = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4)

		var1 = (self.t_fine >> 1) - 64000
		var2 = (((var1 >> 2) * (var1 >> 2)) >> 11) * self.dig_P6
		var2 = var2 + ((var1 * self.dig_P5) << 1)
		var2 = (var2 >> 2) + (self.dig_P4 << 16)
		var1 = (((self.dig_P3 * (((var1 >> 2)*(var1 >> 2)) >> 13)) >> 3) + ((self.dig_P2 * var1) >> 1)) >> 18
		var1 = ((32768 + var1) * self.dig_P1) >> 15
		if var1 == 0:
			return 0

		press = (((1048576 - press_raw) - (var2 >> 12))) * 3125
		if press < 0x80000000:
			press = (press << 1) / var1
		else :
			press = (press / var1) * 2

		var1 = (self.dig_P9 * ((((press >> 3) * (press >> 3)) >> 13))) >> 12
		var2 = (((press >> 2)) * self.dig_P8) >> 13
		press = (press + ((var1 + var2 + self.dig_P7) >> 4))

		return (press/100.0)

	def getHumidity(self):
		data = self.bus.read_i2c_block_data(self.address,0xFD,2)

		hum_raw = (data[0] << 8) | data[1]

		v_x1 = self.t_fine - 76800
		v_x1 =  (((((hum_raw << 14) -((self.dig_H4) << 20) - ((self.dig_H5) * v_x1)) +\
			(16384)) >> 15) * (((((((v_x1 * self.dig_H6) >> 10) *\
			(((v_x1 * (self.dig_H3)) >> 11) + 32768)) >> 10) + 2097152) *\
			self.dig_H2 + 8192) >> 14))
		v_x1 = (v_x1 - (((((v_x1 >> 15) * (v_x1 >> 15)) >> 7) * self.dig_H1) >> 4))
		if v_x1 < 0:
			v_x1 = 0
		if v_x1 > 419430400:
			v_x1 = 419430400
		
		hum = (v_x1 >> 12)
		
		return (hum/1024.0)


bme280 = BME280()
log = open("log.csv","a")
while True:
	temp = round(bme280.getTemperature(),1)
	hum = round(bme280.getHumidity(),1)
	press = round(bme280.getPressure(),1)

	pressCorrect = round((press  * 9.81 * ALTITUDE) / (287 * (273.15 + temp)),1) 
	print_msg =  "Temp,%0.1f,Hum,%0.1f,Press,%0.1f,0m_Press,%0.1f" %(temp,hum,press,press+pressCorrect)
	print print_msg
	log.write(print_msg+"\n")
	xivelyDevice.registToXively('Temperature',temp)
	xivelyDevice.registToXively('Humidity',hum)
	xivelyDevice.registToXively('Pressure-Altitude_600m',press)
	xivelyDevice.registToXively('Pressure-Altitude_0m',press + pressCorrect)
	time.sleep(INTERVAL)

実行と確認

作成したPythonスクリプトを次のコマンドで実行します。

sudo python raspi_xively.py

そして自分のXivelyのURLへ行き、正しくデータが送信されていることを確認します。
f:id:penta_twi:20150701130958p:plain
これであなたの情報が公開されるようになりました、やったね。(Xivelyにはプライベートモードもあるので情報を晒すのが嫌だ、仲間内だけで使いたい場合はそちらをご利用ください。)