電子發(fā)燒友App

硬聲App

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示
創(chuàng)作
電子發(fā)燒友網(wǎng)>電子資料下載>電子資料>LInterp之線性插值PROGMEM數(shù)組生成器

LInterp之線性插值PROGMEM數(shù)組生成器

2022-10-20 | zip | 0.46 MB | 次下載 | 免費(fèi)

資料介紹

描述

LInterp.h是一個(gè)預(yù)處理器腳本,用于使用 Arduino IDE(或任何其他)C 編譯器聲明和初始化大型插值/翻譯/查找數(shù)組。它聲明一個(gè)數(shù)組并從一組提供的映射坐標(biāo)自動(dòng)生成其元素,然后消失,不留下任何代碼、數(shù)據(jù)、定義、類(lèi)或其他任何東西。這對(duì)于 RAM 有限的 Arduino 板來(lái)說(shuō)是理想的,因?yàn)閿?shù)組可以在PROGMEM(程序空間)內(nèi)存更大,并且不需要微控制器代碼來(lái)生成數(shù)組。LInterp對(duì) Arduino 板或引導(dǎo)加載程序一無(wú)所知,并且完全獨(dú)立于硬件。它實(shí)際上解決了生成潛在的大型變換數(shù)組的問(wèn)題因此編譯器可以計(jì)算數(shù)組元素的值并在一次傳遞中初始化數(shù)組。對(duì)于最初(由作者)作為 UNIX shell 腳本編寫(xiě)的具有 40 年歷史的回收件來(lái)說(shuō)還不錯(cuò),以避免使具有類(lèi)似用戶內(nèi)存限制的 VAX 崩潰。

LInterp在 Arduino 微控制器平臺(tái)中最明顯的用途是為連接到模擬輸入的非線性傳感器或換能器生成線性變換。通過(guò)在設(shè)備產(chǎn)生的范圍內(nèi)“映射”一組模擬輸入值(例如作為輸入引腳上的電壓),LInterp生成一個(gè)逆變換數(shù)組,其元素是用戶指定的線性函數(shù)上的均勻間隔點(diǎn)在相同的設(shè)備范圍內(nèi)。如果數(shù)組元素之間的間隔被選擇為大于底層設(shè)備輸入比例(例如ADC范圍),那么通過(guò)相鄰數(shù)組元素之間的插值可以比僅使用最近索引元素更準(zhǔn)確地轉(zhuǎn)換輸入值。LInterp總是在數(shù)組的末尾添加一個(gè)額外的數(shù)組元素,以將上面最后提供的縱坐標(biāo)映射點(diǎn)與有效的數(shù)組元素綁定以進(jìn)行插值(即使數(shù)組被聲明為平面)。

poYBAGNQxHuAf0yfAA8bhZDLX0M760.jpg
?

配置和使用陣列生成器

C 語(yǔ)言預(yù)處理器是一個(gè)原始的文本處理代碼,它通過(guò)擴(kuò)展和替換標(biāo)記定義直到它們?cè)u(píng)估為常量值來(lái)工作。它沒(méi)有循環(huán)、變量或任何運(yùn)行時(shí)上下文的概念,只能進(jìn)行簡(jiǎn)單的整數(shù)運(yùn)算。幸運(yùn)的是,這足以允許從一組映射坐標(biāo)和輸入/輸出縮放參數(shù)生成線性插值數(shù)組。#define在使用#include指令調(diào)用腳本之前,我們將這些常量作為 Arduino 草圖中的語(yǔ)句提供給預(yù)處理器。腳本完成后,它會(huì)刪除與其關(guān)聯(lián)的所有定義,因此可以定義一個(gè)新集合并再次調(diào)用腳本以生成另一個(gè)數(shù)組。LInterp腳本中的所有標(biāo)記都以LI_并且在完成后將是未定義的,因此微控制器代碼所需的任何數(shù)組參數(shù)定義都應(yīng)在源文件的較早部分進(jìn)行,并且LInterp令牌定義引用它們。聲明的數(shù)組名由編譯器單獨(dú)保留。#define語(yǔ)句具有以下語(yǔ)法:

#define token value /* assigns value to token */

或者

#define token /* asserts that token exists from this point onwards in the source file */

以下列表描述了控制LInterp腳本的標(biāo)記。在標(biāo)記表示數(shù)值的情況下,類(lèi)型顯示在括號(hào)中。默認(rèn)值顯示在方括號(hào)中。

LI_ARR[ LInterp] – 數(shù)組的名稱(chēng)。腳本完成后由編譯器保留。

LI_CAL( int) – 陣列基礎(chǔ)“校準(zhǔn)”比例。

LI_INT( int) [1] – 的插值間隔LI_CAL

LI_OFS( float) [0] – 數(shù)組元素常量偏移值。縮放后添加(參見(jiàn)LI_SCL

LI_Pn– 數(shù)組映射縱坐標(biāo)在n =0 到n =32 的范圍內(nèi)。必須聲明至少四個(gè)坐標(biāo)。如果需要超過(guò) 32 個(gè)定義,則必須將定義添加到LInterp腳本(請(qǐng)參閱參考資料LInterp.h)。

LI_RAM– 強(qiáng)制在板 RAM 中聲明數(shù)組,即使pgmspace.h存在。

LI_RNG( int) – 映射縱坐標(biāo)比例LI_Pn

LI_SCL( float) [1.0] - 數(shù)組元素比例系數(shù),=(最后一個(gè)元素值)-(第一個(gè)元素值)(見(jiàn)LI_OFS

LI_TYP– 指定數(shù)組的整數(shù)類(lèi)型,例如byte、intlong。元素將由編譯器計(jì)算為 (float) 并(LI_TYP)在分配給數(shù)組之前四舍五入。

LI_VAR[ const] – 在 RAM 中聲明數(shù)組時(shí)的常量/動(dòng)態(tài)切換。定義LI_VAR(無(wú)值)以允許在聲明后寫(xiě)入數(shù)組。

Arduino 平臺(tái)中LInterp腳本的唯一外部依賴(lài)是宏令牌。如果在調(diào)用腳本之前未包含系統(tǒng)頭文件, LInterp將聲明并初始化 RAM 中的數(shù)組為常量(默認(rèn)情況下)或可修改(如果已定義)。PROGMEMLI_VAR

坐標(biāo)縮放和整數(shù)算術(shù)

要計(jì)算數(shù)組大小和元素間距,預(yù)處理器必須將縱坐標(biāo)映射點(diǎn)值乘以和除以提供的縮放和插值間隔因子,并且它必須僅使用整數(shù)算術(shù)來(lái)執(zhí)行此操作,因?yàn)樗鼪](méi)有可用的浮點(diǎn)類(lèi)型. 記住整數(shù)除法中的 999/1000 = 0(下溢),數(shù)組定義的大小和操作順序?qū)τ讷@得正確的數(shù)組維度很重要。LInterp還在計(jì)算中將提供的常量轉(zhuǎn)換為長(zhǎng)整數(shù),以防止整數(shù)乘法溢出。在為L(zhǎng)Interp配置定義列表時(shí),應(yīng)注意以下數(shù)值注意事項(xiàng):

縱坐標(biāo)地圖比例

縱坐標(biāo)地圖定義LI_P0..及其比例因子應(yīng)使用方便的測(cè)量派生比例,該比例允許地圖值表示為數(shù)組定義所需精度的整數(shù)。LI_PNLI_RNG

數(shù)組基礎(chǔ)(插值)比例

我們希望我們的數(shù)組跨越的整數(shù)比例,并定義我們的插值間隔大小,由 定義LI_CAL。它等于縱坐標(biāo)地圖比例因子LI_RNG乘以一個(gè)常數(shù),但作為一個(gè)單獨(dú)的因子提供,以允許對(duì)由儀器或數(shù)學(xué)上下文強(qiáng)加的數(shù)組使用現(xiàn)有的“自然”索引縮放。

縱坐標(biāo)地圖點(diǎn)陣列基本位置

縱坐標(biāo)映射點(diǎn)( n > 0) 通常不直接對(duì)應(yīng)于數(shù)組索引。包含(使得(int) i( n ) < (float) i( n ) < (int) i( n ) + 1)的數(shù)組元素由下式給出LI_PnLInterp[i] LI_Pn

我( n ) = ( * ) / ( * )LI_PnLI_CALLI_RNGLI_INT

其中算術(shù)運(yùn)算按使用長(zhǎng)整數(shù)顯示的順序執(zhí)行。

數(shù)組大小計(jì)算

使用上面的數(shù)組索引計(jì)算,數(shù)組的大小由第一個(gè) ( LI_P0) 和最后一個(gè) ( ) 映射點(diǎn)給出,即 (# of elements) = i( N ) – i( 0 ) + 1。同樣,算術(shù)運(yùn)算符在沒(méi)有事先簡(jiǎn)化或分組的情況下按所示順序應(yīng)用。顯示的額外元素是添加的最終數(shù)組元素,邊界在上面。LI_PNLI_PN

數(shù)組生成參數(shù)的約束

足夠的縱坐標(biāo)映射

如果規(guī)則間隔的縱坐標(biāo)圖包括連續(xù)縱坐標(biāo)之間的映射函數(shù)的拐點(diǎn)(峰、谷或鞍點(diǎn)),則生成數(shù)組元素的線性?xún)?nèi)插器無(wú)法獲得此信息增加映射點(diǎn)頻率以解決此類(lèi)特征。

不規(guī)則間距縱坐標(biāo)映射集

縱坐標(biāo)映射集 { } 表示被轉(zhuǎn)換的映射函數(shù)的規(guī)則間隔。映射點(diǎn) (P I , S I )的不規(guī)則間隔映射集 {P n , S n }也是正則集,因此定義= P I * ( S I – S i-1 ) 和 S av為平均值集合內(nèi)的間隔 (S I – S i-1 ) 的值產(chǎn)生一個(gè)規(guī)則間隔的映射,其中 ( S 0 – S (-1) ) = S av= [P n scale] * S av 。請(qǐng)記住,區(qū)間和 SLI_PnLI_PiLI_RNGav必須表示為LInterp的整數(shù)

插值范圍限制

LInterp腳本包含足夠的插值元素聲明,在連續(xù)提供的映射縱坐標(biāo)之間提供多達(dá) 32 個(gè)插值數(shù)組元素。嘗試聲明超過(guò)此值將產(chǎn)生致命的編譯錯(cuò)誤和“超出插值限制”消息。聲明這么多插值的嘗試通常表示數(shù)組定義中的縮放錯(cuò)誤或映射函數(shù)的緩慢增加(低梯度)間隔(例如圖形的 P8 到 P9)。由于在數(shù)組中使用許多插值會(huì)降低該縱坐標(biāo)間隔中變換的精度,因此最好在此處聲明更多縱坐標(biāo)映射點(diǎn)(請(qǐng)參閱上面關(guān)于不規(guī)則映射集的說(shuō)明)或增加插值間隔LI_INT. 如果認(rèn)為絕對(duì)有必要增加LInterp腳本中的插值聲明的數(shù)量,請(qǐng)按照LInterp.h文件中顯示的說(shuō)明進(jìn)行操作。

坐標(biāo)映射范圍限制

LInterp腳本包括在多達(dá) 32 個(gè)縱坐標(biāo)映射點(diǎn)之間進(jìn)行插值的定義。如果需要更多,該LInterp.h文件包含有關(guān)如何添加更多映射點(diǎn)定義的說(shuō)明。請(qǐng)注意,文件中有幾個(gè)位置需要這些添加,不要與插值范圍聲明混淆(見(jiàn)上文)。

使用插值數(shù)組

訪問(wèn)LInterp生成的數(shù)組取決于它的聲明位置。如果它已在 RAM 中聲明,則它可以像使用指針 ( *(array+index)) 或下標(biāo) ( array[index]) 表示法的任何其他 C 數(shù)組聲明一樣訪問(wèn)。如果數(shù)組在 RAM 中聲明并LI_VAR定義了令牌,則數(shù)組元素可能會(huì)被微控制器代碼更改。如果數(shù)組是在程序空間內(nèi)存中聲明的PROGMEMpgmspace.h這些函數(shù)具有一般形式

(array_element_type) pgm_read_array_element_type(int pos);

其中array_element_type是標(biāo)準(zhǔn)數(shù)值類(lèi)型例如byte、,并且是程序空間存儲(chǔ)器中要讀取的位置。要訪問(wèn)LInterp生成的程序空間數(shù)組中的第i個(gè)元素,我們提供用i指定的數(shù)組名稱(chēng)for 為了將來(lái)的可移植性和代碼可讀性,將函數(shù)調(diào)用嵌入宏定義中是謹(jǐn)慎的,例如intfloatlongposLI_ARRpos

#define MyArray( i ) pgm_read_float( LInterp + i )

其中使用了默認(rèn)數(shù)組名稱(chēng)LInterp,并且在這種情況下數(shù)組元素類(lèi)型為浮點(diǎn)數(shù)。MyArray()宏可以像代碼中的函數(shù)調(diào)用一樣使用,其參數(shù)計(jì)算為數(shù)組元素索引。有關(guān)pgmspace.h函數(shù)的更多信息,請(qǐng)參閱www.arduino.cc上的PROGMEM庫(kù)參考。

如果LInterp生成的平移數(shù)組平坦的(即LI_INT= 1),因此映射函數(shù)的每個(gè)值都有一個(gè)數(shù)組元素,則上述宏可以直接使用映射函數(shù)的邊界檢查值作為數(shù)組索引. 如果LInterp數(shù)組已指定插值間隔(即LI_INT> 1),因此必須在數(shù)組值之間插值映射函數(shù)值,則必須使用插值函數(shù)來(lái)獲得正確的變換值。例如:

float DeviceToLin ( int dev_value ) {
/* lower bound check */
if ( dev_value < ArrOffset ) dev_value = ArrOffset;
/*upper bound check */
else if ( dev_value > ArrLimit ) dev_value = ArrLimit;
dev_value -= ArrOffset;
int index = dev_value / ArrInterp;
/* lower interpolation bound */
float lwr_bound = MyArray ( index );
/*upper interpolation bound */
float upr_bound = MyArray ( index + 1 );
return( lwr_bound + ( upr_bound – lwr_bound ) * ( dev_value % ArrInterp ) / ArrInterp );
}

withArrInterp等于LI_INT用于創(chuàng)建數(shù)組的插值間隔,dev_value具有與 相同的比例LI_CAL,是對(duì)應(yīng)單位ArrLimit的數(shù)組結(jié)束位置,是對(duì)應(yīng)單位 ( not )的數(shù)組偏移量(如果有)。LInterp數(shù)組生成器確保最后提供的縱坐標(biāo)映射點(diǎn)以有效數(shù)組元素為界。請(qǐng)記住在涉及數(shù)組邊界的任何計(jì)算中使用長(zhǎng)整數(shù),并檢查編譯器的整數(shù)溢出警告。LI_PNLI_CALArrOffsetLI_P0LI_CAL LI_OFSLI_PN

由于 Arduino 環(huán)境中最常見(jiàn)的LInterp應(yīng)用程序是模擬設(shè)備輸出轉(zhuǎn)換,LinDev.h因此提供了一個(gè)大綱頭文件,用于針對(duì)特定設(shè)備定義進(jìn)行定制。這將縱坐標(biāo)圖、LInterp定義、設(shè)備線性變換函數(shù)和輸出函數(shù)封裝在與 Arduino 項(xiàng)目草圖文件分開(kāi)的單個(gè)頭文件中,從而有效地虛擬化設(shè)備。以下示例顯示了將此頭文件用作獨(dú)立的 Arduino 草圖。

示例程序 – PotUnLog.ino

例如,我們考慮使用LInterp來(lái)線性化連接到(任何)Arduino 板的模擬輸入的非線性模擬設(shè)備的部分輸出范圍。對(duì)數(shù)電位器(或?qū)?shù)電位器)是一種可變電阻器,它產(chǎn)生的電阻隨著掃描旋轉(zhuǎn)角的增加而呈指數(shù)增加。如果我們將電阻的一端接地,另一端連接到我們的模擬參考電壓電源Vref (來(lái)自單獨(dú)供電的 Arduino 板),則掃描端子將產(chǎn)生非線性電壓增加,隨著電位器主軸角度的增加,鍋從零旋轉(zhuǎn)到Vref在完全旋轉(zhuǎn)。使用一個(gè) 100K 電位器來(lái)限制從模擬參考電源汲取的電流,將電位器固定在一張紙板上并添加一個(gè)帶有方向指針的旋鈕,我們可以在其整個(gè)旋轉(zhuǎn)范圍(通常為 270度,或 27 度間隔)。如果我們隨后在每個(gè)標(biāo)記位置測(cè)量電位器電壓,我們就有了電位器的常規(guī)縱坐標(biāo)映射集。然后,我們可以將電位器掃描終端連接到 Arduino 板的 A0 模擬輸入,并使用VrefanalogRead()除以特定 Arduino 板的 ADC 電平中的模擬通道全寬來(lái)讀取電位器電壓。

現(xiàn)在,假設(shè)我們想要一個(gè) Arduino 代碼函數(shù),它以 0 到 10 之間的實(shí)數(shù)形式返回電位器方向角。我們可以將電位器電壓analogRead()按比例縮放(10 除以模擬參考電壓),但返回值勝出'不匹配我們?cè)阱佒車(chē)鷺?biāo)記的等間隔刻度,因?yàn)殄伈皇蔷€性的。我們需要使用一個(gè)變換函數(shù)“線性化”電位器輸出。為了我們的示例,我們還指定(出于某種原因)我們希望罐變換在刻度上的位置 3 和 7 之間是線性的,但在此范圍之外保持非線性(但與其平滑連續(xù))。讓我們也忽略這樣一個(gè)事實(shí),即我們知道底池是對(duì)數(shù)的(因此我們可以使用數(shù)學(xué)函數(shù)對(duì)其進(jìn)行線性化),并且需要在四個(gè)標(biāo)記的底池位置之間獲得更好的精度,而不僅僅是它們之間的線性近似。如果我們還測(cè)量刻度上每個(gè)電位器位置之間的電位器電壓,我們總共會(huì)得到九個(gè)映射點(diǎn)來(lái)指定LI_P0我們LI_P8的變換數(shù)組。由于這些必須是整數(shù),因此我們指定它們并LI_RNG以毫伏為單位,后者等于模擬參考電壓Vref. 所有對(duì)數(shù)罐應(yīng)生成示例草圖中所示的相同圖,因?yàn)樗鼈兊闹笖?shù)電阻曲線符合對(duì)數(shù)罐對(duì)數(shù)的 ANSI 標(biāo)準(zhǔn)。

我們現(xiàn)在根據(jù)底池產(chǎn)生的值范圍選擇我們的變換數(shù)組大小,作為 ADC 電平接收。查看縱坐標(biāo)圖,我們所需的線性電位器范圍涵蓋大約 444 個(gè) ADC 電平,如果聲明為“平面”數(shù)組,則將占用 1780 個(gè)字節(jié)。如果我們采用LogPotRes(比如說(shuō))5 個(gè) ADC 級(jí)別的插值大小,我們可以將其減少到 356 字節(jié)。這是明智的,因?yàn)槲覀兊目v坐標(biāo)圖太粗糙而無(wú)法有效使用 (100 / 444 =) 0.23% 的分辨率精度。因此,我們?cè)O(shè)置LI_INT為ADC 電平LogPotResLI_CAL的模擬通道全寬。最后,我們將數(shù)組比例設(shè)置LI_SCL為 10,匹配我們的旋鈕比例,LI_OFS設(shè)置為 3,作為我們指定數(shù)組開(kāi)始的所有數(shù)組元素值的旋鈕比例偏移量LI_P0. 我們還將保留LI_P0and的副本LI_P8(以 mV 為單位,作為長(zhǎng)整數(shù))以在變換函數(shù)中定位我們的線性罐部分的開(kāi)始和結(jié)束。我們現(xiàn)在使用指令調(diào)用LInterp腳本#include,之后我們的數(shù)組被分配、初始化并且對(duì)我們的代碼可見(jiàn),并且所有LI_定義都被刪除。

使用連接到 Arduino 板的串行端口,我們現(xiàn)在可以從setup()函數(shù)中檢查聲明的數(shù)組,就好像它是程序代碼中的常規(guī)數(shù)組聲明一樣。請(qǐng)注意,第一個(gè)元素等于我們對(duì) 的定義LI_OFS,而最后一個(gè)元素(恰好)大于LI_OFS + LI_SCL。該函數(shù)ReadPot()對(duì)電位器模擬通道的多個(gè)讀數(shù)取平均值,并對(duì)電位器電壓進(jìn)行邊界檢查。如果這超出了我們的線性變換范圍,則電壓僅根據(jù)相關(guān)的旋鈕間隔范圍進(jìn)行縮放并返回;否則根據(jù)我們的DeviceToLin()函數(shù)示例對(duì)其進(jìn)行數(shù)組轉(zhuǎn)換。啟動(dòng)該loop()功能后,旋鈕位置應(yīng)在 3 到 7 范圍內(nèi)正確報(bào)告,并且大約在此范圍之外。

常見(jiàn)問(wèn)題及故障診斷

ovf,inf以及nan在數(shù)組末尾附近返回的值

將模擬設(shè)備電平縮放為數(shù)組索引時(shí),請(qǐng)注意與原始縱坐標(biāo)映射參考電壓的差異。如果 ADC 或模擬設(shè)備參考電壓相對(duì)于映射參考電壓發(fā)生漂移,則直接縮放到陣列索引的 ADC 電平可能會(huì)超過(guò)陣列的末端。出于這個(gè)原因,為您的模擬設(shè)備和 Arduino 板 ADC(通過(guò)AREF引腳)使用公共外部參考電壓源始終是一個(gè)好主意。如果設(shè)備電壓漂移是您的 Arduino 應(yīng)用程序中不可避免的限制,請(qǐng)將模擬通道用作設(shè)備電壓監(jiān)視器,并在您的變換陣列索引計(jì)算中對(duì)其進(jìn)行縮放。同樣,假設(shè)標(biāo)稱(chēng)值為LI_RNG當(dāng)使用設(shè)備派生的數(shù)組索引訪問(wèn)時(shí),而不是精確測(cè)量的值可能會(huì)導(dǎo)致數(shù)組太短。(技術(shù)說(shuō)明:請(qǐng)記住,ADC 在滿量程時(shí)總是返回比 Vref 小 1LSB

數(shù)組聲明產(chǎn)生一個(gè)數(shù)組元素 (= ) LI_OFS

選擇導(dǎo)致整數(shù)除法下溢錯(cuò)誤的縮放范圍LI_RNG會(huì)使LI_CAL整個(gè)數(shù)組消失。請(qǐng)參閱縱坐標(biāo)縮放和整數(shù)算術(shù))

數(shù)組邊界處的缺失/重疊值

當(dāng)使用如上例中在設(shè)備范圍的一部分上聲明的平移/插值數(shù)組時(shí),必須注意數(shù)組的邊界是如何由轉(zhuǎn)換函數(shù)代碼確定的。這應(yīng)該使用相同的整數(shù)值(如 long ints)來(lái)完成,該整數(shù)值用于定義相對(duì)于LI_CAL而不是邊界檢查計(jì)算的數(shù)組索引的數(shù)組,這可能會(huì)引入截?cái)噱e(cuò)誤。

(高級(jí)):定義非線性輸出函數(shù)

LInterp腳本可以被定制以在預(yù)處理器的有限能力所施加的嚴(yán)重限制內(nèi)產(chǎn)生一個(gè)編碼非線性輸出函數(shù)的輸出數(shù)組。這可以使用以下形式的宏定義來(lái)實(shí)現(xiàn)

#define LI_OFS( curr_map_pt, next_map_pt, element ) ( /*... arithmetic operations */ )

#define LI_SCL( curr_map_pt, next_map_pt, element ) ( /*... arithmetic operations */ )

并用這些確切的語(yǔ)句替換(一個(gè)或兩個(gè))LI_OFSLI_SCL在文件頂部的元素生成器中:LInterp.h

LI_OFS( LI_LEV, LI_NXT, LI_ELT )

LI_SCL( LI_LEV, LI_NXT, LI_ELT )

以及將數(shù)組聲明初始化器列表中顯示的第一個(gè)元素更改為LI_OFS(0, 1, 0)(或硬編碼的#define 數(shù)字常量)如果LI_OFS更改為宏。數(shù)字標(biāo)記(不是變量)LI_LEVLI_NXT指定映射條目之間的數(shù)字標(biāo)記為每個(gè)插值區(qū)間(如果有)定義,從 1 開(kāi)始,以適合范圍內(nèi)的多個(gè)完整區(qū)間結(jié)束。令牌總是等于+ 1 并且是必要的,因?yàn)轭A(yù)處理器不能將 1 加到令牌上。請(qǐng)注意,上面顯示的第一個(gè)數(shù)組元素是一種特殊情況,其唯一元素值為 0,可以通過(guò)條件測(cè)試來(lái)檢測(cè)和處理,例如LI_PnLI_P(n+1)LI_ELTLI_NXTLI_LEV( ( element== 0 )? .. : .. )在宏中使用三元運(yùn)算符。這三個(gè)數(shù)字標(biāo)記是LInterp腳本中預(yù)處理器唯一可用的上下文信息。

幸運(yùn)的是,LI_OFSandLI_SCL宏僅在編譯過(guò)程中進(jìn)行評(píng)估,其中傳遞的數(shù)字標(biāo)記評(píng)估為整數(shù),并且允許浮點(diǎn)算術(shù)運(yùn)算以及類(lèi)型轉(zhuǎn)換和強(qiáng)制轉(zhuǎn)換。這提供了僅在這三個(gè)“狀態(tài)”標(biāo)記的上下文中計(jì)算輸出函數(shù)的有限能力。映射點(diǎn)分布現(xiàn)在成為輸出函數(shù)的域,由于每個(gè)映射間隔的插值分配將根據(jù)其范圍而變化,這一事實(shí)變得復(fù)雜。鑒于元素生成器仍將計(jì)算LI_SCL與插值數(shù)組元素相乘的線性小數(shù)值,輸出函數(shù)只需定義為LI_LEV如果映射點(diǎn)之間的線性近似足以滿足輸出函數(shù)的精度。作為一個(gè)稍微簡(jiǎn)單的例子,拋物線輸出函數(shù)可以定義為

#define LI_SCL(p,q,r) ( scale_constant * p * p )

并留下LI_OFS一個(gè)常量定義。可以是一個(gè)實(shí)數(shù),作為另一個(gè)語(yǔ)句的標(biāo)記提供輸出函數(shù)宏定義的一個(gè)更有用的示例是更改由縱坐標(biāo)映射中的上下邊界條目定義的變換數(shù)組的單個(gè)區(qū)域的線性輸出函數(shù):scale_constant#define

#define LI_OFS(p,q,r) ( (p < LWR) * OFS1 + (p >= LWR && p < UPR ) * OFS2 + ( p >= UPR ) * OFS3 )

#define LI_SCL(p,q,r) ( ( p < LWR || p >= UPR ) * SCL1 + ( p >= LWR && p < UPR ) * SCL2 )

其中表達(dá)式標(biāo)記是用戶提供的#define 常量,選擇偏移量以使三個(gè)線性部分在縱坐標(biāo)映射條目處連續(xù),編號(hào)為。然后可以使用相同的數(shù)組僅基于輸入索引透明地生成不同的輸出函數(shù),而不是使用三個(gè)數(shù)組和編碼輸入邊界測(cè)試來(lái)在它們之間進(jìn)行選擇。OFSiUPRLWR

LI_ELT如果事先不知道其范圍,宏插值元素編號(hào)標(biāo)記(對(duì)應(yīng)于)在某種程度上是無(wú)用的。這可以從LI_S()宏中獲得并用于為當(dāng)前數(shù)組元素生成一個(gè)實(shí)數(shù)小數(shù)范圍因子:

elt_factor = ( (float) element /

(long) LI_S( curr_map_pt, next_map_pt ) )

其中element從 1 到LI_S()第 0 個(gè)元素定義為前一個(gè)映射間隔的最后一個(gè)元素,或數(shù)組的第一個(gè)元素。

請(qǐng)重命名包含您的自定義設(shè)置的頭文件,因?yàn)橥蛔兊?/font>LInterp變種有偽裝成標(biāo)準(zhǔn)規(guī)格版本從實(shí)驗(yàn)室逃脫并在市民中引起恐慌的習(xí)慣。特別是,請(qǐng)不要因有關(guān)預(yù)處理器腳本的問(wèn)題而惹惱 Arduino 支持人員或論壇版主,這是一種神秘且正確失傳的(黑色)藝術(shù)。可悲的是,您會(huì)在 GitHub 或 StackOverflow 等 C 編程論壇(后者以錯(cuò)誤的預(yù)處理器腳本編寫(xiě)的常見(jiàn)結(jié)果命名)中找到充足的幫助。

歷史記錄

LInterp通過(guò)許多硬件平臺(tái)的進(jìn)化過(guò)程進(jìn)入 Arduino 環(huán)境,從 Beowulf 集群到 GPU 板,無(wú)疑已經(jīng)被重新發(fā)明了很多次。LInterp 之類(lèi)的腳本很可能是C 預(yù)處理器的 ANSI 標(biāo)準(zhǔn)對(duì)其功能保持如此高度限制的歷史原因。提前向任何認(rèn)為他們的推導(dǎo)值得贊揚(yáng)的人道歉;但是作者證明所提供的LInterp腳本和相關(guān)代碼完全是他們自己的作品,沒(méi)有任何版權(quán)責(zé)任(并且有證據(jù),可能在磁帶上)。它本著免費(fèi)開(kāi)源公共分發(fā)的“copyLeft”精神提供。作者對(duì)其使用的任何結(jié)果不承擔(dān)任何責(zé)任。

快樂(lè)插值,

dxb

(古代碼)


下載該資料的人也在下載 下載該資料的人還在閱讀
更多 >

評(píng)論

查看更多

下載排行

本周

  1. 1山景DSP芯片AP8248A2數(shù)據(jù)手冊(cè)
  2. 1.06 MB  |  532次下載  |  免費(fèi)
  3. 2RK3399完整板原理圖(支持平板,盒子VR)
  4. 3.28 MB  |  339次下載  |  免費(fèi)
  5. 3TC358743XBG評(píng)估板參考手冊(cè)
  6. 1.36 MB  |  330次下載  |  免費(fèi)
  7. 4DFM軟件使用教程
  8. 0.84 MB  |  295次下載  |  免費(fèi)
  9. 5元宇宙深度解析—未來(lái)的未來(lái)-風(fēng)口還是泡沫
  10. 6.40 MB  |  227次下載  |  免費(fèi)
  11. 6迪文DGUS開(kāi)發(fā)指南
  12. 31.67 MB  |  194次下載  |  免費(fèi)
  13. 7元宇宙底層硬件系列報(bào)告
  14. 13.42 MB  |  182次下載  |  免費(fèi)
  15. 8FP5207XR-G1中文應(yīng)用手冊(cè)
  16. 1.09 MB  |  178次下載  |  免費(fèi)

本月

  1. 1OrCAD10.5下載OrCAD10.5中文版軟件
  2. 0.00 MB  |  234315次下載  |  免費(fèi)
  3. 2555集成電路應(yīng)用800例(新編版)
  4. 0.00 MB  |  33566次下載  |  免費(fèi)
  5. 3接口電路圖大全
  6. 未知  |  30323次下載  |  免費(fèi)
  7. 4開(kāi)關(guān)電源設(shè)計(jì)實(shí)例指南
  8. 未知  |  21549次下載  |  免費(fèi)
  9. 5電氣工程師手冊(cè)免費(fèi)下載(新編第二版pdf電子書(shū))
  10. 0.00 MB  |  15349次下載  |  免費(fèi)
  11. 6數(shù)字電路基礎(chǔ)pdf(下載)
  12. 未知  |  13750次下載  |  免費(fèi)
  13. 7電子制作實(shí)例集錦 下載
  14. 未知  |  8113次下載  |  免費(fèi)
  15. 8《LED驅(qū)動(dòng)電路設(shè)計(jì)》 溫德?tīng)栔?/a>
  16. 0.00 MB  |  6656次下載  |  免費(fèi)

總榜

  1. 1matlab軟件下載入口
  2. 未知  |  935054次下載  |  免費(fèi)
  3. 2protel99se軟件下載(可英文版轉(zhuǎn)中文版)
  4. 78.1 MB  |  537798次下載  |  免費(fèi)
  5. 3MATLAB 7.1 下載 (含軟件介紹)
  6. 未知  |  420027次下載  |  免費(fèi)
  7. 4OrCAD10.5下載OrCAD10.5中文版軟件
  8. 0.00 MB  |  234315次下載  |  免費(fèi)
  9. 5Altium DXP2002下載入口
  10. 未知  |  233046次下載  |  免費(fèi)
  11. 6電路仿真軟件multisim 10.0免費(fèi)下載
  12. 340992  |  191187次下載  |  免費(fèi)
  13. 7十天學(xué)會(huì)AVR單片機(jī)與C語(yǔ)言視頻教程 下載
  14. 158M  |  183279次下載  |  免費(fèi)
  15. 8proe5.0野火版下載(中文版免費(fèi)下載)
  16. 未知  |  138040次下載  |  免費(fèi)