TI-Nspire & Arduino を利用した温度計 3、温度センサーを複数接続する。

参考: Arduino+DS18B20で温度測定してみた - Qiita

今度は OneWire バスにセンサーを複数乗せる。電源はパラサイトパワーにはせず普通に供給する。
f:id:ti-nspire:20160721065521j:plain:w300 f:id:ti-nspire:20160721070800j:plain:w300
f:id:ti-nspire:20160720134509p:plain:w500

.ino

#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 10

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

DeviceAddress thermo0;
DeviceAddress thermo1;

void setup() {
   Serial.begin(115200);
   sensors.begin();
   sensors.getAddress(thermo0, 0);
   sensors.getAddress(thermo1, 1);
   sensors.setResolution(thermo0, 12);
   sensors.setResolution(thermo1, 12);
}
void loop() {
   if (Serial.read() == 'T') {     
      sensors.requestTemperatures();
      Serial.print("0: ");
      Serial.print(sensors.getTempC(thermo0)); 
      Serial.print(";");
      Serial.print("1: ");
      Serial.print(sensors.getTempC(thermo1));
   }
} 


.lua

-- multi-sensors
require "asi" require "color"
platform.window:setBackgroundColor(color.dodgerblue)

PORT = nil
INTERVAL = 1
DATA = {}
numberOfSensors = 2

function on.resize() 
   W = platform.window:width()
   fontSize = W/13.25
   lineSpace = W/7
end
function whenNoData()
   for i = 1, numberOfSensors do
      DATA[i] = 0 
   end
end

--------------------------------------------------------------------------
-- シリアルデータの読み取り要求函数(合図として文字 "T" を送信する)
--------------------------------------------------------------------------
function requestData()
   if PORT then
      PORT:write('T')
      PORT:read()
   end
end

--------------------------------------------------------------------------------
-- ASI ステートリスナーを定義する(ASI の準備が整ったらポートスキャンを開始する)
--------------------------------------------------------------------------------
function stateListener(state)
   if state == asi.ON then 
      asi.startScanning(portScanner) 
   end
   platform.window:invalidate()   
end

----------------------------------------------------------------
-- ポートスキャナーを定義する(見つかったポートに接続要求を出す)
----------------------------------------------------------------
function portScanner(port)
   port:connect(portConnector) 
end

-----------------------------------------------------------------------------------------------------
-- ポートコネクターを定義する
--(入出力の準備が整ったらポートスキャンを停止し、読み取りリスナーをセットし、データ読み取り要求を出す)
--(接続が外れていたらポートスキャンを開始する)
-----------------------------------------------------------------------------------------------------
function portConnector(port, event) 
   PORT = port
   if event == asi.CONNECTED then
      asi.stopScanning()
      port:setReadListener(readListener)
      requestData()
      timer.start(INTERVAL) -- 初回データを要求してからタイマーをスタートする。
   else
      whenNoData()
      platform.window:invalidate()
      asi.startScanning(portScanner)
   end
end

-----------------------------
-- 読み取りリスナーを定義する
-----------------------------
function readListener(port)
   local data = port:getValue()
   if data then
      local dataList = string.split(data, ";") -- "0: 温度0;1: 温度1" という形式のデータを {0: 温度0, 1: 温度1, ...} というリストに変換する。
      for _, v in ipairs(dataList) do
         local subList = string.split(v, ":") -- さらに {0, 温度0} {1, 温度1} ... というリストに変換し、
         DATA[subList[1] + 1] = subList[2] -- DATA[1] = 温度0、DATA[2] = 温度1 と代入する。
      end
   else
      whenNoData() 
   end
   platform.window:invalidate()
end

---------------------------------
-- ASI ステートリスナーを登録する
---------------------------------
function on.construction()
   asi.addStateListener(stateListener)
end

-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
function on.timer()
   requestData() 
end
function on.paint(gc)
   gc:setFont("sansserif", "r", fontSize)
   gc:setColorRGB(color.white)
   for i, v in ipairs(DATA) do
      gc:drawString(string.format("  %d:   %4.1f °C", (i - 1), v), 0, (i - 1) * lineSpace)
   end
end