Open raspisteve opened 3 years ago
//Temperature Sensor DS18B20 with Display
//- -----------------------------------------------------------------------------------------------------------------------
// AskSin++
// 2020-03-31 papa, extended by steve_cz Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
//- -----------------------------------------------------------------------------------------------------------------------
// define this to read the device id, serial and device type from bootloader section
// #define USE_OTA_BOOTLOADER
#define EI_NOTEXTERNAL
#include <EnableInterrupt.h>
#include <AskSinPP.h>
#include <LowPower.h>
#include <MultiChannelDevice.h>
#include <DallasTemperature.h>
#include <U8g2lib.h>
U8X8_SSD1306_128X32_UNIVISION_SW_I2C u8x8(/* clock=A5*/ 19, /* data=A4*/ 18);
// we use a Pro Mini
// Arduino pin for the LED
// D5 == PIN 5 on Pro Mini
#define LED_PIN 4
// D4 == PIN 4 on Pro Mini
#define DS18B20_PIN 14
// Arduino pin for the config button
// B0 == PIN 8 on Pro Mini
#define CONFIG_BUTTON_PIN 8
//-----------------------------------------------------------------------------------------
//Korrektur von Temperatur und Luftfeuchte
//Einstellbarer OFFSET für Temperatur -> gemessene Temp +/- Offset = Angezeigte Temp.
#define OFFSETtemp 3 //z.B -50 ≙ -5°C / 50 ≙ +5°C
//Einstellbarer OFFSET für Luftfeuchte -> gemessene Luftf. +/- Offset = Angezeigte Luftf.
//#define OFFSEThumi 0 //z.B -10 ≙ -10%RF / 10 ≙ +10%RF
//-----------------------------------------------------------------------------------------
// number of available peers per channel
#define PEERS_PER_CHANNEL 6
//seconds between sending messages
#define MSG_INTERVAL 60 //300
// all library classes are placed in the namespace 'as'
using namespace as;
OneWire ourWire(DS18B20_PIN); // DS18B20_PIN
DallasTemperature sensors(&ourWire);
// define all device properties
const struct DeviceInfo PROGMEM devinfo = {
{0x34, 0x56, 0x83}, // Device ID
"CZET000003", // Device Serial
{0x00, 0x3f}, // Device Model
0x10, // Firmware Version
as::DeviceType::THSensor, // Device Type
{0x01, 0x00} // Info Bytes
};
/**
Configure the used hardware
*/
typedef AvrSPI<10, 11, 12, 13> SPIType;
typedef Radio<SPIType, 2> RadioType;
typedef StatusLed<LED_PIN> LedType; //LED_PIN
typedef AskSin<LedType, BatterySensor, RadioType> Hal;
Hal hal;
class WeatherEventMsg : public Message {
public:
void init(uint8_t msgcnt, int16_t temp, bool batlow) { //uint8_t humidity,
uint8_t t1 = (temp >> 8) & 0x7f;
uint8_t t2 = temp & 0xff;
if ( batlow ) {
t1 |= 0x80; // set bat low bit
}
Message::init(0xc, msgcnt, 0x70, BIDI | WKMEUP, t1, t2);
pload[0] = 0; //humidity;
}
};
class WeatherChannel : public Channel<Hal, List1, EmptyList, List4, PEERS_PER_CHANNEL, List0>, public Alarm { //PEERS_PER_CHANNEL
WeatherEventMsg msg;
int16_t temp;
// uint8_t humidity; //enable to use humidity with another sensor
uint16_t millis;
public:
WeatherChannel () : Channel(), Alarm(5), temp(0), millis(0) {} //, humidity(0)
virtual ~WeatherChannel () {}
// here we do the measurement
void measure () {
//DPRINT("Measure...\n");
sensors.requestTemperatures();
//float t = sensors.getTempCByIndex(0);
//humidity = 0;
temp = sensors.getTempCByIndex(0) * 10;
//DPRINT("T/H = " + String(temp+OFFSETtemp)+"/"+ String(humidity+OFFSEThumi) + "\n");
DPRINT("T/H = " + String(temp+OFFSETtemp)+"\n");
}
virtual void trigger (__attribute__ ((unused)) AlarmClock& clock) {
uint8_t msgcnt = device().nextcount();
// reactivate for next measure
tick = delay();
clock.add(*this);
measure();
msg.init(msgcnt, temp + OFFSETtemp, device().battery().low()); //OFFSETtemp //, 0
if (msgcnt % 20 == 1) device().sendPeerEvent(msg, *this);
else device().broadcastEvent(msg, *this);
displayValue();
}
uint32_t delay () {
return seconds2ticks(MSG_INTERVAL); //MSG_INTERVAL
}
void setup(Device<Hal, List0>* dev, uint8_t number, uint16_t addr) {
Channel::setup(dev, number, addr);
sysclock.add(*this);
}
uint8_t status () const {
return 0;
}
uint8_t flags () const {
return 0;
}
void displayValue() {
//DPRINT("display Value...\n");
//u8x8.clearDisplay(); //enable this to clear display after each measurement
char textArr[10];
dtostrf((temp + OFFSETtemp) / 10.0, 4, 1, textArr);
u8x8.draw2x2String(0, 2, textArr);
}
};
typedef MultiChannelDevice<Hal, WeatherChannel, 1> WeatherType;
WeatherType sdev(devinfo, 0x20);
ConfigButton<WeatherType> cfgBtn(sdev);
void initI2cDisplay() {
u8x8.begin();
u8x8.setFont(u8x8_font_pressstart2p_f);
u8x8.drawString(0, 0, "Temperatur");
u8x8.draw2x2UTF8(12, 2, "°C");
}
void setup () {
DINIT(57600, ASKSIN_PLUS_PLUS_IDENTIFIER);
sensors.begin();
sdev.init(hal);
hal.initBattery(60UL * 60, 22, 19);
buttonISR(cfgBtn, CONFIG_BUTTON_PIN); //CONFIG_BUTTON_PIN
sdev.initDone();
//Display
initI2cDisplay();
}
void loop() {
bool worked = hal.runready();
bool poll = sdev.pollRadio();
if ( !worked && !poll ) {
hal.activity.savePower<Idle<>>(hal);//Sleep
}
}
Hallo zusammen!
Habe einen Sketch erweitert und ihr könnt ihn gerne auf der Homepage verwenden. Es ist der originale HM-WDS40-TH-I-DS18B20 von papa PLUS i2c Display Anbindung, das die Temperatur zeigt.
Display Library: U8g2lib
HM-WDS40-TH-I-DS18B20-Display.zip
Ich musste einiges speicheroptimieren und weglassen, da das Programm sonst nicht in den Arduino Pro Mini Speicher passt. Deswegen ist auch die Konfiguration nicht so komfortabel. Die wichtigsten 3 Dinge wie Button, Led und Sensor Pin sind aber immer noch ganz oben zu konfigurieren.
Stromversorgung wegen des Displays wird empfohlen.
LG Stefan