TI-Nspire & 超音波モジュール / 高性能超音波距離計 LV-MaxSonar-EZ1 から出力される距離データ (ASCII コード) を TI-Nspire で直読する

関連:
高性能超音波距離計LV-MaxSonar-EZ1データシート(非公式和訳) -
シャープ PC-G リンクを使って PC と PC-G850VS とでテキストをやり取りする -
I²C および UART/RS-232C シリアルバスのトリガー・解析機能 -
高性能超音波距離計 LV-MaxSonar-EZ1 から出力される距離データ (ASCII コード) をターミナルで直読する -
 
下のように接続し、MaxSonar から ASCII コード ("R" + "インチ数 (3 桁)" + キャリッジリターン) として出力される距離データを TI-Nspire で読み取る。
f:id:ti-nspire:20171207113146p:plain:w400
 

 

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

local W, H, fontSize
function on.resize() 
   W, H = platform.window:width(), platform.window:height()
   fontSize = W/10
end

local DATA


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

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

-----------------------------
-- ポートコネクターを定義する
-----------------------------
function portConnector(port, event)  
   if event == asi.CONNECTED then
      asi.stopScanning()
      port:setReadListener(readListener)
          :read()
   elseif event == asi.DISCONNECTED then 
      asi.startScanning(portScanner)
   end
   platform.window:invalidate() 
end

-----------------------------
-- 読み取りリスナーを定義する
-----------------------------
function readListener(port)
   DATA = port:getValue() or 0
   port:read()
   platform.window:invalidate()
end

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


-------------------------------------------------------------------------------
function map(var, inMin, inMax, outMin, outMax)
   return (var - inMin) * (outMax - outMin) / (inMax - inMin) + outMin
end
function on.paint(gc)
   gc:setFont("sansserif", "r", fontSize)
   gc:setColorRGB(color.white)
   local inches = tonumber(string.sub(DATA or 0, 2)) or 6 -- 文字列の先頭についている R を string.sub() で削除する。
   local cm  = inches * 2.54
   local str = ""
   if     inches <= 6   then str = " or less"
   elseif inches >= 254 then str = " or more"
   end
   gc:drawString(string.format("%d"   , inches).." in"..str, 0, 0       )
   gc:drawString(string.format("%3.2f", cm    ).." cm"..str, 0, fontSize)
   gc:fillRect(0, H/2, map(inches, 0, 20, 0, W), H/5)
end