Digisparkもどきを3機使って温湿度計付き時計を作りました。I2CでLCD slaveとDHT11 slaveとmasterに使いました。
温湿度計はDHT11モジュールを、RTCにはDS1307モジュールを使いました。DHT11モジュールをI2C slave化しましたが、DS1307モジュールは元々I2C slaveです。
また、I2Cのアダプターも作りました。
DHT11 I2C slave化
を使いましたが、しばらくするとスタックするので一行変更しました。
--- DHT11.org.cpp 2025-12-29 04:36:08.083639058 +0900
+++ DHT11.cpp 2025-12-29 04:37:40.234498236 +0900
@@ -103,7 +103,7 @@
{
value |= (1 << (7 - i));
}
- while (digitalRead(_pin) == HIGH)
+ for (unsigned int j = 0; digitalRead(_pin) == HIGH && j < 65535; j++)
;
}
return value;
slaveのコードは、
#include <Wire.h>
#include <DHT11.h>
#define I2C_SLAVE_ADDRESS 0x25
#define READING_IN_PROGRESS 100;
DHT11 dht11(1);
struct vals {
int result;
int temperature;
int humidity;
};
union uni {
struct vals vals;
byte b[6];
};
int result, temperature, humidity;
void requestEvent() {
union uni uni;
uni.vals.result = result;
uni.vals.temperature = temperature;
uni.vals.humidity = humidity;
Wire.write(uni.b, 6);
}
void setup() {
digitalWrite(4, LOW);
Wire.begin(I2C_SLAVE_ADDRESS);
Wire.onRequest(requestEvent);
}
unsigned long previousMillis = 0;
const long interval = 3000;
void loop()
{
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
//result = READING_IN_PROGRESS;
result = dht11.readTemperatureHumidity(temperature, humidity);
}
}
です。
DS1307モジュール
DS1307モジュールには、
を使いました。
マスタープログラム
masterはこの様にしました。
#include <LCD_I2C.h>
#include <Wire.h>
#include <DS1307.h>
LCD_I2C lcd = LCD_I2C(0x23, 16, 2);
DS1307 clock;
struct vals {
int result;
int temperature;
int humidity;
};
union uni {
struct vals vals;
byte b[6];
};
void setup() {
lcd.init();
clock.begin();
/*
clock.fillByYMD(2025, 12, 29); //Jan 19,2013
clock.fillByHMS(3, 20, 0); //15:28 30"
clock.fillDayOfWeek(MON);//Saturday
clock.setTime();//write time to the RTC chip
*/
Wire.begin();
}
void printTime() {
clock.getTime();
lcd.home();
if (clock.hour < 10) lcd.print("0");
lcd.print(clock.hour, DEC);
lcd.print(":");
if (clock.minute < 10) lcd.print("0");
lcd.print(clock.minute, DEC);
lcd.print(":");
if (clock.second < 10) lcd.print("0");
lcd.print(clock.second, DEC);
lcd.setCursor(0, 1);
lcd.print(clock.year + 2000, DEC);
lcd.print("/");
if (clock.month < 10) lcd.print("0");
lcd.print(clock.month, DEC);
lcd.print("/");
if (clock.dayOfMonth < 10) lcd.print("0");
lcd.print(clock.dayOfMonth, DEC);
}
void printTemp() {
uint8_t num_byte = Wire.requestFrom(0x25, 6);
if (num_byte != 6) {
lcd.clear();
lcd.home();
lcd.print("i2c error");
delay(3000);
return;
}
union uni uni;
uint8_t i = 0;
while (Wire.available() > 0) {
byte b = Wire.read();
uni.b[i++] = b;
}
if (uni.vals.result == 0) {
lcd.setCursor(12, 0);
lcd.print(" ");
lcd.setCursor(12, 0);
lcd.print(uni.vals.temperature);
lcd.write(0xdf);
lcd.print("C");
lcd.setCursor(13, 1);
lcd.print(" ");
lcd.setCursor(13, 1);
lcd.print(uni.vals.humidity);
lcd.print("%");
} else {
lcd.clear();
lcd.home();
lcd.print("ERROR");
lcd.setCursor(0, 1);
lcd.print(uni.vals.result);
}
}
void loop() {
printTime();
printTemp();
delay(1000); digitalWrite(0, HIGH);
}
TODO
- 電波時計にしたい。追記 aitendoのD606Cを購入した
が、うまく動作しない。出力信号にLEDをつけても、点滅しない。2つ目も買ったが、同様。動作しました。digisparkもどき - 電波時計(D606C)へ続く
