徒然なる日々を送るソフトウェアデベロッパーの記録(2)

技術上思ったことや感じたことを気ままに記録していくブログです。さくらから移設しました。

TWE-Lite で K熱電対温度計を作る

というわけで(だいぶ間が空いたが、前回からの続き)TWE-Lite で K熱電対温度計を作ったのでそのメモです。

温度の読み出しには adafruit キットの MAX31855 を使用した。最近の IC は高機能で楽ちんですな。

この IC は CS をアサートすると SCLK に同期して 32 ビットのデータが出てくるので SCLK=Hi のときに読みだすとデータを取得することができる。

今回は PORT_OUTPUT4→CS, PORT_OUTPUT3→SCLK, PORT_INPUT4→DO と接続してみた。

データ読み出し(MAX31855.c)はこんな感じ。

/*
 * MAX31855.c
 *
 *  Created on: 2014/11/10
 *      Author: Minosys
 */

#include <jendefs.h>
#include <AppHardwareApi.h>
#include "MAX31855.h"
#include "utils.h"

#define MAX31855_WAIT (10)


/**
 * MAX31855 ポートの初期化
 * @return
 */
bool_t MAX31855_init(void) {
	uint32 init;
	vPortAsOutput(PORT_OUT4); // CS
	vPortAsOutput(PORT_OUT3); // SCLK
	vPortAsInput(PORT_INPUT4); // DO

	init = MAX31855_read();
	return !MAX31855_oc(init);
}

uint32 MAX31855_read(void) {
	int i;
	uint32 result = 0;

	// CS を hi にする
	vPortSetHi(PORT_OUT4);

	// SCLK を lo にする
	vPortSetLo(PORT_OUT3);

	// 少し待つ
	vWait(MAX31855_WAIT);

	// CS を lo にする
	vPortSetLo(PORT_OUT4); // 読み出し開始

	for (i = 0; i < 32; ++i) {
		vWait(MAX31855_WAIT);
		vPortSetHi(PORT_OUT3); // SCLK = hi
		vWait(MAX31855_WAIT);
		result <<= 1;
		if (!bPortRead(PORT_INPUT4)) {
			result |= 1; // bPortRead はロジックを反転することに注意
		}
		vPortSetLo(PORT_OUT3); // SCLK = lo
	}
	vWait(MAX31855_WAIT);

	// CS を hi にする
	vPortSetHi(PORT_OUT4);
	return result;
}

MAX31855.h はこんな感じ。

/*
 * MAX31855.h
 *
 *  Created on: 2014/11/10
 *      Author: Minosys
 */

#ifndef MAX31855_H_
#define MAX31855_H_

#include <serial.h>
#include <fprintf.h>

//#include "flash.h"
//#include "serialInputMgr.h"


#include "config.h"
#include "common.h"

#include "Version.h"

// MAX31855 を初期化する
bool_t MAX31855_init(void);

uint32 MAX31855_read(void);

// -------------------- 取得したデータのビット --------------------------
#define MAX31855_OC 0x1

#define MAX31855_oc(result) ((result & MAX31855_OC)?TRUE:FALSE)

#endif /* MAX31855_H_ */

読みだしたデータの上位14ビットを右シフトすれば温度が取り出せる(分解能0.25℃)。

def parseMAX31855(data):
        # 先頭の : を取り除く
        if data[0] != ":":
                return False
        data = data[1:]

        # バイトデータに変換する
        ss = struct.Struct(">BBBBlB")
        data = binascii.unhexlify(data.rstrip())
        parsed = ss.unpack(data);

        # 温度データを温度に変換
        temp = (parsed[4] >> 18) * 0.25

        # error ビットを解釈
        error = parsed[4] & 0x07

        # 現在時刻
        now = datetime.datetime.now()
        current = now.strftime("%Y-%m-%d %H:%M:%S")

        # 結果を返す
        result = {
                "type" : "max31855",
                "datetime" : current,
                "current" : int(time.mktime(now.timetuple())),
                "from" : parsed[0],
                "presence" : 128,
                "status" : error,
                "temperature" : temp,
                "humidity": 0,
        }
        return result;