Skip to content

Instantly share code, notes, and snippets.

@mohitbhoite
Last active April 20, 2025 21:59
Show Gist options
  • Save mohitbhoite/9ef05cf86a1761a5065c83b34404c659 to your computer and use it in GitHub Desktop.
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
//
// 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
}
//----------------------------------------------------------------------------
#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);
}
//----------------------------------------------------------------------------
#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_
@hector4060
Copy link

hector4060 commented Feb 20, 2025

Problem programming Arduino sketch.

  • error: 'setup_watchdog' was not declared.....any help will be apreciated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment