Arduino+温度センサ(DS18B20)+フルカラーLEDで遊ぶ
フルカラーのLEDを手に入れたので点灯試験を兼ねて遊んでみました。
参考サイトの「色彩表示温度計」は面白いのですがいかんせん表示の段数が少ないのでどうしても変化時の滑らかさが足りません。
では、表示段数を増やせばいいのではと思うのですがそうするとarduinoの貧弱なメモリが悲鳴を上げます…。
どうしたものかと考えた結果、参考サイトの「RGBLEDの色を段々に変化点灯」で使用しているHSV色空間の連続変化と組み合わせれば何とかなるのではないかと考えた結果です。
■構成
Arduino:ATMega328P
Temp:DS18B20
LED:RGBLED(カソードコモン)抵抗値は適当に計算して合わせました。
■回路図
■スケッチ
#include <OneWire.h> // DS18B20
byte addr[8],type_s; ; // 情報読み込み用
OneWire ds(7); // 入力ピン
float intervalOut = 1000; // 結果出力間隔(ms)
float tempMin = 10; // 摂氏最低値( ℃ )
float tempMax = 35; // 摂氏最高値( ℃ )
// RGB-LED出力ピン設定
#define ledPinRed 9
#define ledPinGreen 10
#define ledPinBlue 11
void setup() {
Serial.begin(19200);
pinMode(ledPinRed, OUTPUT);
pinMode(ledPinGreen, OUTPUT);
pinMode(ledPinBlue, OUTPUT);
// OneWire DS18S20, Temperature Sensor
if ( ds.search(addr)) {
if (OneWire::crc8(addr, 7) == addr[7]) {
// the first ROM byte indicates which chip
switch (addr[0]) {
case 0x10:
Serial.println(“Chip = DS18S20”);
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;
}
Serial.print(“ROM =”);
for( uint8_t i = 0; i < 8; i++) {
Serial.write(‘ ‘);
Serial.print(addr[i], HEX);
}
Serial.println();
} else {
Serial.println(“CRC is not valid!”);
return;
}
} else {
Serial.println(“No more addresses.”);
Serial.println();
ds.reset_search();
delay(250);
return;
}
}
void loop() {
int cVal;
float tempC;
int Red,Green,Blue;
tempC = ReadTemp(); // 温度計測
tempC = constrain(tempC, tempMin, tempMax) * 10; // 色彩表示範囲温度設定
cVal = map(tempC, tempMin *10, tempMax *10, 300, 0); // 色空間の中での位置を設定
// 色空間内でのRGBを取得する
if (cVal <= 120) {
/* H値(0-120) 赤–黄–緑 */
Red = map(cVal,0,120,255,0); // 赤LED R←→G
Green = map(cVal,0,120,0,255); // 緑LED G←→R
Blue = 0;
} else if (cVal <= 240) {
/* H値(120-240) 緑–水色–青 */
Green = map(cVal,120,240,255,0); // 緑LED G←→B
Blue = map(cVal,120,240,0,255); // 青LED B←→G
Red = 0;
} else {
/* H値(240-360) 青–紫–赤 */
Blue = map(cVal,240,360,255,0); // 青LED B←→R
Red = map(cVal,240,360,0,255); // 青LED R←→B
Green = 0;
}
// RGB-LEDへの出力処理
analogWrite(ledPinRed, Red);
analogWrite(ledPinGreen, Green);
analogWrite(ledPinBlue, Blue);
// シリアル出力処理
Serial.print(” Temp/”);
Serial.print(intervalOut / 1000);
Serial.print(“sec | AverageTemp: “);
Serial.print(tempC / 10);
Serial.print(“, cVal: “);
Serial.print(cVal);
Serial.print(“, RGB: “);
Serial.print(Red);
Serial.print(“,”);
Serial.print(Green);
Serial.print(“,”);
Serial.println(Blue);
delay(intervalOut); // 次回更新待ち時間
}
double ReadTemp(){
static byte dataC[12];
static double celsius, fahrenheit;
ds.reset();
ds.select(addr);
ds.write(0x44,1); // start conversion, with parasite power on at the end
ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad
for ( uint8_t i = 0; i < 9; i++) { // we need 9 bytes
dataC[i] = ds.read();
}
// convert the data to actual temperature
unsigned int raw = (dataC[1] << 8) | dataC[0];
if (type_s) {
raw = raw << 3; // 9 bit resolution default
if (dataC[7] == 0x10) {
// count remain gives full 12 bit resolution
raw = (raw & 0xFFF0) + 12 – dataC[6];
}
} else {
byte cfg = (dataC[4] & 0x60);
if (cfg == 0x00) raw = raw << 3; // 9 bit resolution, 93.75 ms
else if (cfg == 0x20) raw = raw << 2; // 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 = (double)raw / 16.0;
return celsius;
}
■参考サイト
arduino使い方:RGBLEDの色を段々に変化点灯 http://www.geocities.jp/zattouka/GarageHouse/micon/Arduino/RGBLED/RGBLED1.htm
色彩表示温度計シールド (arduino): Modelisme hebdomadaire http://skt48.cocolog-nifty.com/blog/2011/04/post-8fbb.html
OneWire Arduino Library, connecting 1-wire devices (DS18S20, etc) to Teensy http://www.pjrc.com/teensy/td_libs_OneWire.html
コメントはまだありません。