Arduino夏休み<架空>ワークショップ②「温度計を作る」 3回で読み切りの最後 温度を測る

 Arduino IDEがインストールできたら、プログラム(Arduinoではスケッチという)を書いていきます。ほぼCもしくはC++言語です。

温度を測る

 温度センサDS18B20のライブラリを導入します。

 メニューのツールから、「ライブラリを管理」を選択します。

 ライブラリマネージャが立ち上がります。検索欄にDS18B20と入れて、少し経つと検索してきます。

 たくさんあるので、どれでもよいのですが、一番上の DallasTempretureの右端にある「インストール」をクリックして、インストールしますが、途中で、次のパネルが出ます。別のライブラリONEWIREも一緒にインストールするかというので、そうします。

 Dallasというのは、このセンサを最初に作った半導体の会社名です。通信プロトコルのONEWIRE(1-wire)もこの会社が作りました。その後、マキシムに買収されました。現在、マキシムはアナログ・デバイセズに買収されました。

 ライブラリは、サンプルとともにインストールされます。

サンプル・スケッチの導入

 メニューのファイルから、スケッチ例->Onewire->DS18x20_Temperaterを選択します。

 アイコンの矢印をクリックしてコンパイルします。コンパイルが終わると、マイコンへ書き込みをします。下の青い帯の部分に「ボードへの書き込みが完了しました。」という表示が出たら、右上のシリアルモニタのアイコン(虫眼鏡)をクリックします。

 シリアルモニタは、デフォルトの通信速度が9600bpsです。スケッチの中でも9600になっていれば、そのまま出力が見れます。

 シリアルモニタに表示されている「ROM」は、センサ固有のアドレスです。複数つながっていれば、探し出してくれます。

 必要な情報は、 Temperater 28.50  Celsius です。つまり摂氏28.5度です。

 1-wireのプロトコルは単純ではありません。ライブラリを使わずに自分でスケッチを描くのは、とても大変です。

OLEDディスプレイをつなぐ

 アマゾンで購入したOLEDディスプレイ(I2Cインターフェース)をArduino UNOにつなぎます。ピンヘッダをはんだ付けしてからメスーオス・タイプのジャンパピンで配線します。はんだ付けをしなくても、次のジャンパピンで接続はできます。

   サンハヤト スルホール用テストワイヤ TTW-200 

OLEDディスプレイ Arduino UNO
GND GND
Vcc 3.3V
SCL SCL
SDA SDA

 ライブラリを導入します。検索欄にSSD1306を入れて出てきた Adafruit SSD1306をインストールします。

 途中で、前出のようにパネルが出て、別のライブラリも一緒にインストールするかというので、そうします。

 サンプルssd1306_128x32_i2Cを読み込みます。

 コンパイルして実行します。

合体

 さきの温度を測るDS18x20_Temperaterに、表示部分のssd1306_128x32_i2Cから必要な部分を抜き出し、摂氏の温度だけを表示するように合体しました。


#include <OneWire.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h> #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 32 // OLED display height, in pixels // OneWire DS18S20, DS18B20, DS1822 Temperature Example // http://www.pjrc.com/teensy/td_libs_OneWire.html // The DallasTemperature library can do all this work for you! // https://github.com/milesburton/Arduino-Temperature-Control-Library OneWire ds(10); // on pin 10 (a 4.7K resistor is necessary) #define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin) #define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); #define NUMFLAKES 10 // Number of snowflakes in the animation example void setup(void) { Serial.begin(9600); // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) { Serial.println(F("SSD1306 allocation failed")); for(;;); // Don't proceed, loop forever } } void loop(void) { byte i; byte present = 0; byte type_s; byte data[12]; byte addr[8]; float celsius, fahrenheit; if ( !ds.search(addr)) { Serial.println("No more addresses."); Serial.println(); ds.reset_search(); delay(250); return; } display.display(); delay(2000); // Pause for 2 seconds // Clear the buffer display.clearDisplay(); Serial.print("ROM ="); for( i = 0; i < 8; i++) { Serial.write(' '); Serial.print(addr[i], HEX); } if (OneWire::crc8(addr, 7) != addr[7]) { Serial.println("CRC is not valid!"); return; } Serial.println(); // the first ROM byte indicates which chip switch (addr[0]) { case 0x10: Serial.println(" Chip = DS18S20"); // or old DS1820 type_s = 1; break; case 0x28: Serial.println(" Chip = DS18B20"); type_s = 0; break; case 0x22: Serial.println(" Chip = DS1822"); type_s = 0; break; default: Serial.println("Device is not a DS18x20 family device."); return; } ds.reset(); ds.select(addr); ds.write(0x44, 1); // start conversion, with parasite power on at the end delay(1000); // maybe 750ms is enough, maybe not // we might do a ds.depower() here, but the reset will take care of it. present = ds.reset(); ds.select(addr); ds.write(0xBE); // Read Scratchpad Serial.print(" Data = "); Serial.print(present, HEX); Serial.print(" "); for ( i = 0; i < 9; i++) { // we need 9 bytes data[i] = ds.read(); Serial.print(data[i], HEX); Serial.print(" "); } Serial.print(" CRC="); Serial.print(OneWire::crc8(data, 8), HEX); Serial.println(); // Convert the data to actual temperature // because the result is a 16 bit signed integer, it should // be stored to an "int16_t" type, which is always 16 bits // even when compiled on a 32 bit processor. int16_t raw = (data[1] << 8) | data[0]; if (type_s) { raw = raw << 3; // 9 bit resolution default if (data[7] == 0x10) { // "count remain" gives full 12 bit resolution raw = (raw & 0xFFF0) + 12 - data[6]; } } else { byte cfg = (data[4] & 0x60); // at lower res, the low bits are undefined, so let's zero them if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms //// default is 12 bit resolution, 750 ms conversion time } celsius = (float)raw / 16.0; fahrenheit = celsius * 1.8 + 32.0; Serial.print(" Temperature = "); Serial.print(celsius); Serial.print(" Celsius, "); Serial.print(fahrenheit); Serial.println(" Fahrenheit"); display.setTextSize(2); // Draw 2X-scale text display.setTextColor(SSD1306_WHITE); display.setCursor(10, 0); display.println(celsius); display.display(); // Show initial text delay(100); }

 USBポートをもつ充電器をUSBケーブルでArduino IDEにつなぎ、温度を表示しました。持ち運びができます。

前へ

Arduino夏休み<架空>ワークショップ②「温度計を作る」 3回で読み切りの2回目 Arduino IDEの準備

次へ

ArduinoでIoTにチャレンジ<その1>まずはIoT対応のArduinoを使ってみる