Last active
April 20, 2025 21:59
-
-
Save mohitbhoite/9ef05cf86a1761a5065c83b34404c659 to your computer and use it in GitHub Desktop.
A solar powered temperature and humidity monitor using ATtiny85 microcontroller and SHT31 sensor. Displayed on a four digit LCD
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Project link: https://www.bhoite.com/sculptures/satellite-2202/ | |
// | |
#include "Adafruit_SHT31.h" | |
//#include <TinyWireM.h> | |
//#include <USI_TWI_Master.h> | |
#include <avr/sleep.h> //Needed for sleep_mode | |
#include <avr/wdt.h> //Needed to enable/disable watch dog timer | |
//Following is the header file for the LCD module bought on ebay | |
//Seller link https://www.ebay.com/itm/284843842249 | |
//Information on the LCD http://www.hexpertsystems.com/LCD/ | |
#include <cdm4101.h> | |
int ctr=1000; | |
CDM4101 LCD; | |
char data[25]; | |
int temperature = 0; | |
bool displayToggle = 0; | |
uint8_t loopCnt = 0; | |
Adafruit_SHT31 sht31 = Adafruit_SHT31(); | |
void setup() | |
{ | |
pinMode(3, INPUT_PULLUP); | |
pinMode(4, INPUT_PULLUP); | |
pinMode(5, INPUT_PULLUP); | |
pinMode(1, INPUT_PULLUP); | |
ADCSRA &= ~(1<<ADEN); //Disable ADC, saves ~230uA | |
// put your setup code here, to run once: | |
//TinyWireM.begin(); | |
Wire.begin(); | |
sht31.begin(0x44); | |
LCD.Init(); | |
LCD.DispStr("sat6"); | |
delay(1000); | |
set_sleep_mode(SLEEP_MODE_PWR_DOWN); //Power down everything, wake up from WDT | |
sleep_enable(); | |
} | |
//This runs each time the watch dog wakes us up from sleep | |
ISR(WDT_vect) { | |
//watchdog_counter++; | |
displayToggle=!displayToggle; | |
} | |
void loop() | |
{ | |
setup_watchdog(9); //Setup watchdog to go off after 8sec | |
sleep_mode(); //Go to sleep! Wake up 8 sec later | |
int temperature = (sht31.readTemperature()*1.8)+32; | |
//int temperature = sht31.readTemperature(); | |
int humidity = sht31.readHumidity(); | |
if (displayToggle) | |
{ | |
//insure that the temperature is in a valid range | |
if ((temperature <110) && (temperature > -20)) | |
{ | |
sprintf(data,"%doF",temperature); | |
LCD.DispStr(data); | |
} | |
} | |
else | |
{ | |
//insure that the humidity is in a valid range | |
if ((humidity <101) && (humidity > 0)) | |
{ | |
sprintf(data,"%drH",humidity); | |
LCD.DispStr(data); | |
} | |
} | |
} | |
//Sets the watchdog timer to wake us up, but not reset | |
//0=16ms, 1=32ms, 2=64ms, 3=128ms, 4=250ms, 5=500ms | |
//6=1sec, 7=2sec, 8=4sec, 9=8sec | |
//From: http://interface.khm.de/index.php/lab/experiments/sleep_watchdog_battery/ | |
void setup_watchdog(int timerPrescaler) { | |
if (timerPrescaler > 9 ) timerPrescaler = 9; //Limit incoming amount to legal settings | |
byte bb = timerPrescaler & 7; | |
if (timerPrescaler > 7) bb |= (1<<5); //Set the special 5th bit if necessary | |
//This order of commands is important and cannot be combined | |
MCUSR &= ~(1<<WDRF); //Clear the watch dog reset | |
WDTCR |= (1<<WDCE) | (1<<WDE); //Set WD_change enable, set WD enable | |
WDTCR = bb; //Set new watchdog timeout value | |
WDTCR |= _BV(WDIE); //Set the interrupt enable, this will keep unit from resetting after each int | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//---------------------------------------------------------------------------- | |
#include <stdio.h> | |
#include <string.h> | |
#include <inttypes.h> | |
#include "Arduino.h" | |
#include "Wire.h" | |
#include "cdm4101.h" | |
//---------------------------------------------------------------------------- | |
#define I2C_ADDR (0x38) | |
#define CMD_MODE_SET 0xCD | |
#define CMD_LOAD_DP 0x80 | |
#define CMD_DEVICE_SEL 0xE0 | |
#define CMD_BANK_SEL 0xF8 | |
#define CMD_NOBLINK 0x70 | |
#define CMD_BLINK 0x71 | |
#define DASH 10 | |
#define UNDERSCORE 11 | |
#define SPACE 12 | |
#define ASTERISK 39 | |
#define ALPHA_START 13 | |
#define HOLD_TIME 8 | |
//---------------------------------------------------------------------------- | |
static byte const Segs[] = | |
{ | |
0x6F, // 0x30 0 | |
0x03, // 0x31 1 | |
0x5D, // 0x32 2 | |
0x57, // 0x33 3 | |
0x33, // 0x34 4 | |
0x76, // 0x35 5 | |
0x7E, // 0x36 6 | |
0x43, // 0x37 7 | |
0x7F, // 0x38 8 | |
0x77, // 0x39 9 | |
0x10, // - | |
0x04, // _ | |
0x00, // space | |
0x7B, // A | |
0x3E, // b | |
0x6C, // C | |
0x1F, // d | |
0x7C, // E | |
0x78, // F | |
0x77, // G | |
0x3B, // H | |
0x02, // i | |
0x0F, // J | |
0x38, // K - can't do | |
0x2C, // L | |
0x5A, // M - can't do | |
0x1A, // n | |
0x6F, // O | |
0x79, // P | |
0x75, // Q - can't do | |
0x18, // r | |
0x76, // S | |
0x3C, // t | |
0x0E, // u | |
0x2F, // V - can't do | |
0x4E, // W - can't do | |
0x2B, // X - can't do | |
0x37, // y | |
0x5D, // Z | |
0x71, // ° - use * to represent it in your string | |
}; | |
//---------------------------------------------------------------------------- | |
void CDM4101::Update(void) | |
{ | |
byte data[5]; // bytes to send display segments | |
if(Ctr) | |
{ | |
Ctr--; | |
return; | |
} | |
Wire.beginTransmission(I2C_ADDR); | |
Wire.write(CMD_MODE_SET); | |
Wire.write(CMD_LOAD_DP); | |
Wire.write(CMD_DEVICE_SEL); | |
Wire.write(CMD_BANK_SEL); | |
if(Blink) Wire.write(CMD_BLINK); | |
else Wire.write(CMD_NOBLINK); | |
#if 1 | |
data[0] = (Digits[0] >> 4); // || LCD_BAR | |
data[1] = (Digits[0] << 4) | (Digits[1] >> 3); | |
data[2] = (Digits[1] << 5) | (Digits[2] >> 2); | |
data[3] = (Digits[2] << 6) | (Digits[3] >> 1); | |
data[4] = (Digits[3] << 7); | |
#else | |
Wire.write(0x70); | |
Wire.write(0x3B); | |
Wire.write(0xB5); | |
Wire.write(0xD9); | |
Wire.write(0x80); | |
#endif | |
for(int i=0;i<5;i++) Wire.write(data[i]); | |
Wire.endTransmission(); | |
} | |
//---------------------------------------------------------------------------- | |
void CDM4101::Init(void) | |
{ | |
Blink = 0; | |
Digits[0] = Segs[SPACE]; | |
Digits[1] = Segs[SPACE]; | |
Digits[2] = Segs[SPACE]; | |
Digits[3] = Segs[SPACE]; | |
Wire.beginTransmission(I2C_ADDR); | |
Wire.write(CMD_MODE_SET); | |
Wire.write(CMD_LOAD_DP); | |
Wire.write(CMD_DEVICE_SEL); | |
Wire.write(CMD_BANK_SEL); | |
Wire.write(CMD_NOBLINK); | |
Wire.write(0x05); | |
Wire.write(0xD5); | |
Wire.write(0x9B); | |
Wire.write(0xFF); | |
Wire.write(0x00); | |
Wire.endTransmission(); | |
Ctr = 0; | |
} | |
//---------------------------------------------------------------------------- | |
void CDM4101::Command(byte cmd) | |
{ | |
switch(cmd) | |
{ | |
case CDM4101_BLINK_OFF : | |
Blink = 0; | |
Update(); | |
break; | |
case CDM4101_BLINK_ON : | |
Blink = 1; | |
Update(); | |
break; | |
case CDM4101_CLEAR : | |
Digits[0] = Segs[SPACE]; | |
Digits[1] = Segs[SPACE]; | |
Digits[2] = Segs[SPACE]; | |
Digits[3] = Segs[SPACE]; | |
Update(); | |
break; | |
default : | |
break; | |
} | |
} | |
//---------------------------------------------------------------------------- | |
char CDM4101::ConvertChar(char c) | |
{ | |
if((c >= 'a') && (c <= 'z')) c = c - 'a' + ALPHA_START; | |
else | |
if((c >= 'A') && (c <= 'Z')) c = c - 'A' + ALPHA_START; | |
else | |
if((c >= '0') && (c <= '9')) c = c - '0'; | |
else | |
if(c == '-') c = DASH; | |
else | |
if(c == '_') c = UNDERSCORE; | |
else | |
if(c == '*') c = ASTERISK; | |
else c = SPACE; | |
return c; | |
} | |
//---------------------------------------------------------------------------- | |
void CDM4101::DispChar(byte index, char c) | |
{ | |
Digits[(int)index] = Segs[(int)(ConvertChar(c))]; | |
Update(); | |
} | |
//---------------------------------------------------------------------------- | |
void CDM4101::DispStr(char *s) | |
{ | |
byte i,c; | |
for(i=0;i<CDM4101_NUM_DIGITS;i++) Digits[i] = Segs[SPACE]; | |
i = 0; | |
while((i < 4) && s[i]) | |
{ | |
c = Segs[(int)(ConvertChar(s[i]))]; | |
Digits[i] = c; | |
i++; | |
} | |
Update(); | |
} | |
//---------------------------------------------------------------------------- | |
void CDM4101::DispStrTimed(char *s) | |
{ | |
DispStr(s); | |
Ctr = HOLD_TIME; | |
} | |
//---------------------------------------------------------------------------- | |
// display a decimal value, right justified. | |
void CDM4101::DispDec(short n) | |
{ | |
byte i; | |
char str[5]; | |
if(n < -999L) n = -999L; | |
if(n > 9999L) n = 9999L; | |
for(i=0;i<5;i++) str[i] = 0; | |
itoa(n, str, 10); | |
while(str[3] == 0) | |
{ | |
for(i=3;i>0;i--) str[i] = str[i-1]; | |
str[0] = ' '; | |
} | |
DispStr(str); | |
} | |
//---------------------------------------------------------------------------- |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef _CDM4101_H_ | |
#define _CDM4101_H_ | |
#include <inttypes.h> | |
//---------------------------------------------------------------------------- | |
#define CDM4101_NUM_DIGITS 4 | |
//---------------------------------------------------------------------------- | |
// LCD commands. | |
#define CDM4101_BLINK_OFF 6 | |
#define CDM4101_BLINK_ON 7 | |
#define CDM4101_CLEAR 8 | |
//---------------------------------------------------------------------------- | |
class CDM4101 | |
{ | |
public: | |
void Init(void); | |
void Command(byte cmd); | |
void DispChar(byte index, char c); | |
void DispStr(char *s); | |
void DispStrTimed(char *s); | |
void DispDec(short n); | |
private: | |
void Update(void); | |
char ConvertChar(char c); | |
byte Digits[CDM4101_NUM_DIGITS]; | |
byte Blink; | |
byte Ctr; | |
}; | |
//---------------------------------------------------------------------------- | |
#endif // _CDM4101_H_ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Problem programming Arduino sketch.