恐れるこずをやめおmbedを愛する方法[パヌト3]

ARM mbed環境を䜿甚しおプロトタむプの枬定デバむスを䜜成するこずに関する䞀連の出版物を続けおいたす。



今日はセンサヌを接続したす。







発行サむクルの内容





3番目の郚分はカットの䞋にありたす。



前の蚘事は、mbed IDEで䜜成され、RiverdiのTFTディスプレむに2番目のカりンタヌの出力を実装するプロゞェクトの説明で終わりたした。



今日、HYTシリヌズの枩床および盞察湿床センサヌを接続したす。 センサヌは完党なデゞタルナニットです。湿床を枬定するための容量性感知玠子、枩床センサヌ、信号凊理回路が含たれおいたす。さらに、ほずんどの同様のセンサヌず同様に、HYTには工堎校正がありたす。 これはすべお1぀のこずを意味したす。センサヌを䜿甚するには、センサヌを制埡コントロヌラヌに接続し、センサヌをポヌリングするプロトコルをマスタヌするだけです。



パッケヌゞの圢匏ず、Cでの察応する関数の実装䟋に぀いおは、 この蚘事で詳しく説明したす 。 ここで、既に述べたこずの倚くを繰り返さないようにし、mbedプロゞェクトでHYT-271 *センサヌを䜿甚する問題に焊点を圓おたす。



* HYTシリヌズは、HYT-271、HYT-221、およびHYT-939の3぀のモデルで構成されおいたす。 ケヌスのみが異なるため、HYT-271をオンにするこずに぀いお私が曞いたものはすべお、他のモデルにも関連しおいたす。





包含回路




HYTシリヌズセンサヌを接続するには、通垞I2Cむンタヌフェむスが䜿甚されたすSPI付きのセンサヌはリク゚ストに応じお利甚可胜です。 したがっお、センサヌを接続するには、次の4぀のラむンが必芁です。







SDAおよびSLCラむンの掚奚プルアップ抵抗定栌は2.4 kOhmです。



センサヌポヌリング手順




HYTシリヌズセンサヌは、いく぀かのタむプのコマンドをサポヌトしおいたす。 枬定芁求およびデヌタフェッチコマンドは、センサヌを盎接ポヌリングするために䜿甚され、残りの呜什は、I2Cバス䞊の暙準センサヌアドレスを倉曎する必芁がある堎合にのみ必芁になりたす。



mbed-library HYTには、I2Cアドレスを倉曎する機胜がないこずをすぐに蚀わなければなりたせん。 その理由は、私の自然な怠ず盎接的な必芁性の欠劂です。ほずんどの堎合、単䞀のセンサヌがバスにぶら䞋がっおいお、動䜜のためにポヌリングず枬定結果の受信を実装するのに十分です。





したがっお、枬定芁求コマンドを受信するず、HYTセンサヌはスリヌプモヌドを終了し、枬定を行い、枩床ず湿床のデヌタを含むパッケヌゞを生成したす。 デヌタを受信するには、Data Fetchコマンドをセンサヌに送信する必芁があり、これら2぀のコマンドの送信の間に100ミリ秒の遅延を提䟛する必芁がありたす。 これは、センサヌがパッケヌゞを枬定しお圢成するのにかかる時間です。



枬定芁求は、ヘッダヌバむトセンサヌアドレスずレコヌドフラグのみで構成されるパケットです。 察応するMRCommand関数は、空のパケットをI2Cに送信したす。



Data Fetchコマンドは、読み取りフラグず、コントロヌラヌがセンサヌから受信する4バむトのデヌタを含むヘッダヌバむトです。





最初のバむトの最初のビットは、サヌビスCModeビットです。 「1」に蚭定されおいる堎合、センサヌは特別な動䜜モヌドにあり、バス䞊のアドレスを倉曎できたす。



最初のバむトの2番目のビットは、サヌビスの叀いビットです。 「1」に蚭定されおいる堎合、次の枬定サむクルを実行した埌、前のサむクルず同じ枩床ず湿床の倀が取埗されたす。



次の14桁は盞察湿床を゚ンコヌドし、次の14桁は枩床を゚ンコヌドしたす。 次は2぀の重芁でないビットです。



察応する関数DFCommandは、察応するパケットをI2Cに送信し、センサヌから受信したデヌタをデコヌドしたす。 盞察湿床ず枩床は、次の匏を䜿甚しお蚈算されたす。



RH [] =100 /2 14-1* RH in

T [°C] =165 /2 14-1* T in -40


したがっお、HYTセンサヌポヌリングラむブラリは、MRCommandずDFCommandの2぀の関数を実装する必芁がありたす。



mbedでラむブラリを䜜成しお公開する




mbedは、さたざたなARMプラットフォヌムず関連デバむス コンポヌネント-ディスプレむ、ドラむブ、センサヌ、トランシヌバヌなどをサポヌトしおいるこずを思い出させおください。



圓然、マむクロコントロヌラのメヌカヌのみが新しいデバッグボヌドのサポヌトを提䟛できたすが、新しい呚蟺コンポヌネントのサポヌトにより、すべおがより興味深いものになりたす。 数か月前、すべおのナヌザヌが新しいデバむスを远加し、サポヌトされおいるコンポヌネントのリストの䞊に[新しいコンポヌネントを远加]ボタンがハングしおいたした。 珟圚、ARMはポリシヌを倉曎しおいたす登録枈みのナヌザヌは新しいコンポヌネントのラむブラリず説明を公開できたすが、サポヌトされおいるコンポヌネントのリストにドラむバヌを远加するには、拡匵暩限が必芁です私はこれらを持っおいたす、hee hee hee。



呚蟺機噚甚のmbedラむブラリはすべお、デバむスの操䜜に必芁な機胜を含むC ++クラスです。 原則ずしお、そのようなクラスのコンストラクタヌは、コンポヌネントが接続されおいる入力/出力行を入力ずしお受け取りたす。 デバむスの接続時に特定の初期化手順が必芁な堎合、この手順はクラスコンストラクタヌに含めるこずも論理的です。 初期化手順を含むラむブラリの䟋ずしおは、FT800グラフィックスコントロヌララむブラリがありたす。詳现に぀いおは、 前の蚘事で説明したした 。



HYTセンサヌの堎合、すべおがはるかに簡単です。センサヌの初期化は䞍芁で、枬定結果を取埗するために必芁な機胜は2぀だけです。



HYT.hファむル

#define HYT_ADDR 0x50 // 01010000 class HYT { public: /** * HYT constructor. * * @param sda mbed pin to use for SDA line of I2C interface. * @param scl mbed pin to use for SCL line of I2C interface. * * Remember about pull-up resistors on sda and scl. Recommended value is 2.4 kΩ */ HYT(PinName sda, PinName scl); /** * @brief The totals (temperature in Celsius, relative humidity in percentages) */ float humidity; float temperature; /** * @brief Send "Measuring Request" command * @details Initiates a measuring cycle of HYT sensor * @details More information: http://www.ist-ag.com/eh/ist-ag/resource.nsf/imgref/Download_AHHYTM_E2.2.5.pdf/$FILE/AHHYTM_E2.2.5.pdf */ void MRCommand(void); /** * @brief Send "Data Fetch" command & processing the data * @details Fetch the last measured value of humidity and temperature from sensor * @details Calculate values of temperature in Celsius, relative humidity in percentages * @details More information: http://www.ist-ag.com/eh/ist-ag/resource.nsf/imgref/Download_AHHYTM_E2.2.5.pdf/$FILE/AHHYTM_E2.2.5.pdf * @returns 0 if no errors, -1 if no new value received from sensor. */ int DFCommand(void); private: I2C _i2c; };
      
      





HYT.cppファむル

 #include "HYT.h" #include "mbed.h" HYT::HYT(PinName sda, PinName scl) : _i2c(sda, scl) { } /*************************************************************************************************************************/ void HYT::MRCommand(void) { _i2c.write(HYT_ADDR, 0, 0); } /*************************************************************************************************************************/ int HYT::DFCommand(void) { char dataI2C[4]; int stateBit; int humidityRaw; int temperatureRaw; _i2c.read(HYT_ADDR, dataI2C, 4); stateBit = (dataI2C[0] & 0x40) >> 6; if (stateBit == 0) { humidityRaw = ((dataI2C[0] & 0x3F) << 8) | dataI2C[1]; temperatureRaw = ((dataI2C[2] << 8) | dataI2C[3]) >> 2; if (temperatureRaw < 0x3FFF && humidityRaw < 0x3FFF) { temperature = ((float)(temperatureRaw) * 165.0f / 16383.0f) - 40.0f; humidity = (float)humidityRaw * 100.0f / 16383.0f; } else { // sensor returns wrong data (1111...11) return -1; } } else { // no new value received from sensor return 0; } return 0; }
      
      





独自のプロゞェクトでラむブラリを䜿甚するには、ペヌゞぞのリンクにその説明を入力し、ラむブラリをオンラむンコンパむラにむンポヌトするだけです。







新しいコンポヌネントのmbedラむブラリを公開するずき、コヌドを䜜成しお適切に文曞化するだけでなく、 さらに、ラむブラリにハヌドりェアモゞュヌル、䞀般的なデバむススむッチング回路、およびHello Worldプログラムの説明ラむブラリを䜿甚する簡単な䟋を提䟛するこずが望たしいです。 このような䟋を䜜成するために、私はこの発行サむクルの最初の蚘事のドラフトプロゞェクトを再び䜿甚したす 。



ドラフトプロゞェクトは、シリアルむンタヌフェむス仮想COMポヌトに2番目のカりンタヌを衚瀺する単玔なプログラムです。
 #include "mbed.h" Serial pc(USBTX, USBRX); Ticker timeKeeping; volatile uint64_t seconds = 0; void secondsCallback(void) { pc.printf("Number of seconds: %x\r\n", seconds); seconds ++; } int main() { timeKeeping.attach(&secondsCallback, 1.0f); while(1) {} }
      
      











HYTラむブラリヌをドラフトプロゞェクトに接続し、いく぀かの簡単な倉曎を行いたす。





したがっお、䜜成されたラむブラリのデモを取埗したす。



 #include "mbed.h" #include "HYT.h" Serial pc(USBTX, USBRX); Ticker timeKeeping; HYT SENSOR (PD6, PD7); // sda, scl [SLSTK3400A] //HYT SENSOR (D14, D15); // sda, scl [WIZwiki-W7500P] //HYT SENSOR (PA08, PA09); // sda, scl [ATSAMD21-XPRO] // HYT sensor polling cycle void dataUpdate(void) { SENSOR.MRCommand(); wait_ms(100); SENSOR.DFCommand(); } void secondsCallback(void) { pc.printf("Humidity level: %.1f\r\n%", SENSOR.humidity); pc.printf("Temperature level: %.1f\r\n%", SENSOR.temperature); pc.printf("-------------------------------\r\n%", SENSOR.temperature); } int main() { timeKeeping.attach(&secondsCallback, 1.0f); while(1) { dataUpdate(); } }
      
      





このプロゞェクトはdeveloper.mbed.orgで入手でき、ARM mbedでサポヌトされおいるさたざたなデバッグボヌドで正垞に動䜜したす。





䜿甚䟋が公開されるず、HYTセンサヌ甚のラむブラリを䜜成するプロセスが終了したす。



独自のプロゞェクトでラむブラリを䜿甚する




これでメむンプロゞェクトに戻り、TFTタッチスクリヌンに2番目のカりンタヌではなく、HYT-271センサヌから受信したデヌタを衚瀺したす。





これを行うには、mbedで新しいプロゞェクトを䜜成し、そこにHYTおよびFT800_2ラむブラリをむンポヌトしたす。

次に、I2CおよびSPIむンタヌフェヌスが䜿甚可胜なI / Oラむンの名前を匕数ずしお䜿甚しお、HYTおよびFT800クラスのオブゞェクトを䜜成したす。



 HYT SENSOR (PD6, PD7); // sda, scl [SLSTK3400A] FT800 TFT (PE10, PE11, PE12, PE13, PB11, PD4); // mosi, miso, sck, ss, int, pd [SLSTK3400A] //HYT SENSOR (D14, D15); // sda, scl [WIZwiki-W7500P] //FT800 TFT (D11, D12, D13, D10, D9, D8); // mosi, miso, sck, ss, int, pd [WIZwiki-W7500P] //HYT SENSOR (PA08, PA09); // sda, scl [ATSAMD21-XPRO] //FT800 TFT (PA18, PA16, PA19, PA17, PA20, PA21); // mosi, miso, sck, ss, int, pd [ATSAMD21-XPRO]
      
      





センサヌポヌリング機胜を远加したす。



 void dataUpdate(void) { SENSOR.MRCommand(); wait_ms(100); SENSOR.DFCommand(); }
      
      





衚瀺リストを䜜成しおグラフィックコントロヌラヌに読み蟌む関数を远加したす。





 void drawTimeScreen(void) { TFT.DLstart(); TFT.DL(CLEAR_COLOR_RGB(255, 255, 255)); TFT.DL(CLEAR(1, 1, 1)); TFT.DL(COLOR_RGB(0, 0, 0)); TFT.Text(11, 15, 30, 0, "Demo-project for habrahabr.ru"); TFT.Text(13, 15 + 40, 28, 0, "Using FT800 library and HYT library"); TFT.DL(COLOR_RGB(9, 40, 3)); TFT.DL(BEGIN(RECTS)); TFT.DL(VERTEX2II(11, 105, 0, 0)); TFT.DL(VERTEX2II(11 + 222, 105 + 100, 0, 0)); TFT.DL(COLOR_RGB(255, 255, 255)); TFT.Text(11 + 10, 105 + 10, 28, 0, "Relative humidity, %"); TFT.Number(11 + 10, 105 + 10 + 30, 31, 0, SENSOR.humidity); TFT.DL(COLOR_RGB(9, 3, 40)); TFT.DL(BEGIN(RECTS)); TFT.DL(VERTEX2II(11 + 222 + 14, 105, 0, 0)); TFT.DL(VERTEX2II(11 + 222 + 14 + 222, 105 + 100, 0, 0)); TFT.DL(COLOR_RGB(255, 255, 255)); TFT.Text(11 + 222 + 14 + 10, 105 + 10, 28, 0, "Temperature, C"); TFT.Number(11 + 222 + 14 + 10, 105 + 10 + 30, 31, 0, SENSOR.temperature); TFT.DL(COLOR_RGB(0, 0, 0)); TFT.Text(300, 105 + 100 + 35, 28, 0, "e-mail: xk@efo.ru"); TFT.DL(BEGIN(LINES)); TFT.DL(LINE_WIDTH(8)); TFT.DL(VERTEX2II(11, 15 + 40 + 30, 0, 0)); TFT.DL(VERTEX2II(460, 15 + 40 + 30, 0, 0)); TFT.DL(DISPLAY()); TFT.Swap(); }
      
      





そしお、継続的にデヌタを曎新しお衚瀺したす



 int main() { while(1) { dataUpdate(); drawTimeScreen(); } }
      
      





プロゞェクトはdeveloper.mbed.orgで入手できたす。



プロゞェクト開発の残りの段階ず同様に、SiLabsのSLSTK3400A、AtmelのATSAMD21-XPRO、WiznetのWIZwiki-W7500Pの3぀の異なるボヌドで結果のプログラムを実行したす。





前回の蚘事で、TFTディスプレむに情報を衚瀺するデモ䟋を芋るず、あるボヌドから別のボヌドに切り替える必芁がありたした。

aタヌゲットプラットフォヌムコンパむラの右䞊隅を倉曎したす。

bディスプレむの接続に䜿甚される結論をコヌドで再割り圓おし、

cディスプレむを新しいボヌドに接続したす。



移行はスムヌズに進み、mbedプログラムはすぐに3぀のボヌドすべおで機胜し始めたした。 HYTセンサヌをポヌリングするプログラムには、次のものも必芁です。

dセンサヌの接続に䜿甚される結論をコヌドで再割り圓おし、

dプルアップ抵抗を忘れずに、センサヌを新しいボヌドに接続したす。



センサヌが接続されるず、デバッグボヌドの違いがようやく明らかになり始めたした。



Wiznetは驚くこずなく動䜜したした。掚奚スキヌムに埓っおセンサヌを接続し、ファヌムりェアをダりンロヌドするだけで十分でした。







SiLabsボヌドからのデヌタは、個別の抵抗を䜿甚しなくおも取埗されたした。 実際、すべおのGPIOマむクロコントロヌラヌEFM32にはプルアップ抵抗が組み蟌たれおいるため、デスクトップIDE Simplicity Studioで䜜業する堎合、各ラむンの動䜜モヌドオヌプンドレむンプッシュプルなどは手動で構成されたす。 どうやら、mbedはSDAずSCLが実装されおいるラむンを自動的にプルしたした。







そしお今日、Atmelが最も匱いリンクであるこずを宣蚀したす-ATSAMD21-XPROボヌドでは、I2CむンタヌフェむスTWIずも呌ばれたすは、Atmel Embedded Debuggerが同時に䜿甚する回線で利甚できたす。 この問題を詳现に理解しおいたせんでしたが、事実は残りたす。ボヌドにUSBから電力が䟛絊されるず、2〜3秒埌にI2Cデヌタの受信が停止したす。 別の5.0V INコネクタに電源を䟛絊した堎合、プログラム党䜓が正しく動䜜したす。







ただし、゜フトりェアの動䜜に぀いお苊情がなかったこずを認める必芁がありたす。぀たり、mbedを䜿甚しお開発を継続するこずが理にかなっおいたす。



次の蚘事では、プログラム構造の簡単な抂芁ず、Riverdi TFTモゞュヌルでタッチ入力を操䜜するための詳现な手順を説明したす。 したがっお、私たちは本栌的なアプリケヌションにどんどん近づいおきおおり、その動䜜はビデオで実蚌されおいたす。







おわりに




結論ずしお、私は䌝統的に読者の泚意に感謝し、Habréに぀いお曞いおいる補品の䜿甚に関する質問は、私のプロフィヌルで指定されたメヌルアドレスにも送信できるこずを思い出させたす。



All Articles