TI-Nspire & Lua / DAC で任意波形を描くための波形テーブルを生成する 1 / 任意の数式を波形テーブルにする

関連: TI-Nspire & Lua / DAC で任意波形を描くための波形テーブルを生成する 2 / interpolate() 使う -


f:id:ti-nspire:20170325091159p:plain:w300
.lua

function createWave(func)
   local POW = math.pow
   local FLOOR = math.floor
   local CEIL = math.ceil
   local MIN = math.min
   local MAX = math.max
   local unpack = table.unpack or unpack

   local numOfBits = 8 -- DAC の分解能 (ビット数)
   local Vdd = 3.3     -- リファレンス電圧(+)
   local Vss = 0       -- リファレンス電圧(-)
   local voltDiff = Vdd - Vss
   local numOfData = 1024 -- 1 周期ぶんのデータの数
   local function seq(from, to, step)
            local list = {}
            for i = from, to, (step or 1) do
               list[#list+1] = i
            end
            return list
         end
   local function round(x, digits)
            local exp = POW(10, (digits or 0))
            if x >= 0 then
               return FLOOR(x * exp + 0.5) / exp
            else
               return CEIL(x * exp - 0.5) / exp
            end
         end
   local function map(var, inMin, inMax, outMin, outMax)
            return (var - inMin) * (outMax - outMin) / (inMax - inMin) + outMin
         end
   return function(Tstart, Tstop, Vmin, Vmax)
             local listA = {}
             local STEP = (Tstop - Tstart) / numOfData
             for i = Tstart, Tstop, STEP do -- 始点から次の始点まで計算しているので 1 回余計に計算しているがここでは抛っておく。
                listA[#listA+1] = func(i)
             end
             
             -- 計算結果の最小値 ~ 最大値を指定の範囲に map する。
             local rawMin = MIN(unpack(listA))
             local rawMax = MAX(unpack(listA))
             local dataUpperLimit = POW(2, numOfBits) - 1
             local dataMin = (Vmin/(voltDiff)) * (dataUpperLimit)
             local dataMax = (Vmax/(voltDiff)) * (dataUpperLimit)
             local listB = {}
             for i = 1, numOfData do
                listB[#listB+1] = round(map(listA[i], rawMin, rawMax, dataMin, dataMax))
             end

             -- 結果は全部 Nspire へ返す。
             var.store("xvalue", seq(0, numOfData - 1))
             var.store("yvalue", listB)
          end
end

-- 確かめてみる
-- この函数を波形テーブルに格納する。
function pulse(x)
   local SIN = math.sin
   local sute = 0
   for i = 1, 3, 2 do
      sute = sute + SIN(i * x) / i
   end
   return sute
end
createWave(pulse)(0, 2 * math.pi, 0.5, 3) -- 0 ~ 2 pi を 1 周期として、上の函数を最小値 0.5 V、最大値 3 V で波形テーブル化する。