#define T_DISPLAY 7500ul //uS display time for each digit
#define T_DEADBAND 40ul //uS blanking time between digits
#define T_DHT_UPDT 37 //# no. of display cycles between DHT reads
#define NUM_DIGITS 4 //# no. of display digits
//these constants can be used to tailor the logic sense of the anodes and cathodes
//to match your actual hardware (if not the same as this simulation)
#define SEGS_OFF 0x00 // all segments off for blanking
#define SEG_INVERT 0x00 // use 0xff to invert SEG outputs, 0x00 for std SEG output
#define DIG_INVERT 0xff // use 0xff to invert DIG outputs, 0x00 for std DIG output
const uint8_t pinDHT11 = 4; // DHT11 data pin
//
const uint8_t pinData = 5; //shift register control lines
const uint8_t pinClock = 6;
const uint8_t pinLatch = 7;
//const uint8_t pinDebug = LED_BUILTIN;
//digit SEG patterns
const uint8_t
num[] =
{
//Dgfedcba
0b00111111, //0
0b00000110, //1
0b01011011, //2
0b01001111, //3
0b01100110, //4
0b01101101, //5
0b01111101, //6
0b00000111, //7
0b01111111, //8
0b01101111 //9
};
//fixed SEG patterns for 'oC' in digits 3 and 4
const uint8_t
//Dgfedcba
degree = 0b01100011,
C = 0b00111001;
//this variable is set in the blanking phase when the DHT11 line has been
//released and data should be ready to read out, which occurs in the
//3rd digit display period
bool
bDHTData = false;
//tens and ones digit segment patterns stored here
uint8_t
tens = 0,
ones = 0;
//digit table; order is 10s, 1s, 'o' and 'C'
const uint8_t grDigitSel[] = {0x40, 0x20, 0x10, 0x80};
//table of pointers to characters to display; order matches digits above
const uint8_t *pgrValues[] = {&tens, &ones, °ree, &C};
//output of DHT11 here
int humidity;
int temperature;
//human-readable display names
enum eDispStates
{
DEADBAND=0, //blanking period between segs to reduce/prevent "smear" or "ghosting"
DIGIT_DISP //digit is actively being displayed
};
void setup()
{
//Serial.begin(115200);
pinMode( pinDHT11, INPUT );
pinMode( pinData, OUTPUT );
pinMode( pinClock, OUTPUT );
pinMode( pinLatch, OUTPUT );
//pinMode( pinDebug, OUTPUT );
}
void loop()
{
DisplayTemp();
}//loop
void DisplayTemp()
{
static uint8_t
state = DIGIT_DISP,
dht = T_DHT_UPDT,
index = 0;
static uint32_t
tDisplay = 0ul;
uint32_t tNow = micros();
// for min 30Hz update rate on a 4 digit displays you have ~8mS
// per display
// allow 100uS per digit deadband
//
// 1 2 3 4 1 ...
// -------|+|-------|+|-------|+|-------|+|------- ...
// A B*** A ...
//
// where '-' is digit display and '+' is deadband (no digit on)
// A = start of start pulse to DHT sensor
// B = end of pulse to DHT sensor
// C = read data from DHT sensor
//
tNow = micros();
switch( state )
{
case DEADBAND:
//last active 7seg is off now (blanking); time to turn on the next?
if( (tNow - tDisplay) >= T_DEADBAND )
{
//set up for timing the digit display
//turn on the next digit
//it has been preloaded so all we have to
//do is latch it over
digitalWrite( pinLatch, HIGH );
tDisplay = micros();
//is a DHT read scheduled (or active) this frame?
if( index == 0 )
{
//count display frames
// we want to update the sensor roughly every 1.2-seconds or so
// (close to its own sample rate). Each frame is about 32mS (giving
// about ~30Hz) so 1.2/0.032 ~= 37
dht--;
if( dht == 0 )
{
dht = T_DHT_UPDT;
pinMode( pinDHT11, OUTPUT );
digitalWrite( pinDHT11, LOW );
}//if
}//if
else if( index == 2 )
{
if( digitalRead( pinDHT11 ) == LOW )
{
digitalWrite( pinDHT11, HIGH );
bDHTData = true; //set the data flag
}//if
}//else
//we have just started displaying this digit so go time its
//display period
state = DIGIT_DISP;
}//if
break;
case DIGIT_DISP:
//is DHT11 data ready?
if( bDHTData == true )
{
bDHTData = false;
//...read it now
DHTread(pinDHT11);
//and process the temperature digits for display
temperature = constrain( temperature, 0, 99 );
ones = num[temperature % 10];
tens = num[temperature / 10];
}//if
if( (tNow - tDisplay) >= T_DISPLAY )
{
//turn off current digit for blanking
digitalWrite( pinLatch, LOW );
shiftOut(pinData, pinClock, MSBFIRST, (grDigitSel[index] ^ DIG_INVERT));
shiftOut(pinData, pinClock, MSBFIRST, (SEGS_OFF ^ SEG_INVERT));
digitalWrite( pinLatch, HIGH );
//index to the next digit
index++;
if( index == NUM_DIGITS )
index = 0;
//and preload the value for this next digit into the shift reg
// but don't raise latch yet; that is done after the blanking period
digitalWrite( pinLatch, LOW );
shiftOut( pinData, pinClock, MSBFIRST, (grDigitSel[index] ^ DIG_INVERT) );
shiftOut( pinData, pinClock, MSBFIRST, (*pgrValues[index] ^ SEG_INVERT) );
//we've blanked the current digit and have pre-loaded the
//next digit's pattern; go time the blanking period
tDisplay = micros();
state = DEADBAND;
}//if
break;
}//switch
}//DisplayTemp
//modified DFRobot read() method
//see https://github.com/DFRobot/DFRobot_DHT11
void DHTread( uint8_t pin )
{
uint8_t bits[5];
uint8_t cnt = 7;
uint8_t idx = 0;
for (int i=0; i< 5; i++)
bits[i] = 0;
//modification of library occurs here
// these delays are removed
//delay(200);
//pinMode(pin, OUTPUT);
//digitalWrite(pin, LOW);
//delay(18);
//digitalWrite(pin, HIGH);
//delayMicroseconds(40);
digitalWrite(pin,LOW);
pinMode(pin, INPUT);
unsigned int loopCnt = 10000;
while(digitalRead(pin) == LOW)
{
if(loopCnt-- == 0)
{
break;
}
}
loopCnt = 30000;
while(digitalRead(pin) == HIGH)
{
if(loopCnt-- == 0)
{
break;
}
}
for(int i=0;i<40;i++)
{
loopCnt = 10000;
while(digitalRead(pin) == LOW)
{
if(loopCnt-- == 0){
break;
}
}
unsigned long t = micros();
while(digitalRead(pin) == HIGH)
{
if(loopCnt-- == 0){
break;
}
}
if ((micros() - t) > 50)
bits[idx] |= (1 << cnt);
if (cnt == 0)
{
cnt = 7;
idx++;
}
else
{
cnt--;
}
}
humidity = bits[0];
temperature = bits[2];
}//DHTRead
mega:SCL
mega:SDA
mega:AREF
mega:GND.1
mega:13
mega:12
mega:11
mega:10
mega:9
mega:8
mega:7
mega:6
mega:5
mega:4
mega:3
mega:2
mega:1
mega:0
mega:14
mega:15
mega:16
mega:17
mega:18
mega:19
mega:20
mega:21
mega:5V.1
mega:5V.2
mega:22
mega:23
mega:24
mega:25
mega:26
mega:27
mega:28
mega:29
mega:30
mega:31
mega:32
mega:33
mega:34
mega:35
mega:36
mega:37
mega:38
mega:39
mega:40
mega:41
mega:42
mega:43
mega:44
mega:45
mega:46
mega:47
mega:48
mega:49
mega:50
mega:51
mega:52
mega:53
mega:GND.4
mega:GND.5
mega:IOREF
mega:RESET
mega:3.3V
mega:5V
mega:GND.2
mega:GND.3
mega:VIN
mega:A0
mega:A1
mega:A2
mega:A3
mega:A4
mega:A5
mega:A6
mega:A7
mega:A8
mega:A9
mega:A10
mega:A11
mega:A12
mega:A13
mega:A14
mega:A15
sr1:Q1
sr1:Q2
sr1:Q3
sr1:Q4
sr1:Q5
sr1:Q6
sr1:Q7
sr1:GND
sr1:Q7S
sr1:MR
sr1:SHCP
sr1:STCP
sr1:OE
sr1:DS
sr1:Q0
sr1:VCC
sr2:Q1
sr2:Q2
sr2:Q3
sr2:Q4
sr2:Q5
sr2:Q6
sr2:Q7
sr2:GND
sr2:Q7S
sr2:MR
sr2:SHCP
sr2:STCP
sr2:OE
sr2:DS
sr2:Q0
sr2:VCC
sevseg1:A
sevseg1:B
sevseg1:C
sevseg1:D
sevseg1:E
sevseg1:F
sevseg1:G
sevseg1:DP
sevseg1:DIG1
sevseg1:DIG2
sevseg1:DIG3
sevseg1:DIG4
sevseg1:COM
sevseg1:CLN
dht1:VCC
dht1:SDA
dht1:NC
dht1:GND