[PA-03c] Read temperature DHT21 with Qt

Another useful code from Vannevar Morgan, you can check these out:
youtube: https://www.youtube.com/watch?v=1PNn63P793Y

github: https://github.com/vannevar-morgan/Qt-Temperature-Sensor

However, I do not use the temperature DS18B20. I use temperature and humidity DHT21. And in Qt code, I use Celcius degree instead of Fahrenheit degree. In Arduino code, I use header file floatToString to display the data to LCD.

 pyqt_dht.ino


/*
 * Date: Wed, 10/05/2017
 * Desc: Read Temperature and Humidity from DHT21
 * Display on LCD
 * Send to PC via serial
 */
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#include "DHT.h"
#include "floatToString.h"

#define I2C_ADDR 0x3F 
#define BACKLIGHT_PIN 3
#define En_pin 2
#define Rw_pin 1
#define Rs_pin 0
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7
LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);

#define DHTPIN 9
#define DHTTYPE DHT21
DHT dht(DHTPIN, DHTTYPE);
float t;
float h;
char bufferstore[20]; // used by floatToString to display on LCD

void setup() {
 delay(1000);
 // Initialize Serial
 Serial.begin(9600); 
 // Initialize DHT
 dht.begin();

// Initialize LCD
 lcd.begin(16,2);
 lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
 lcd.setBacklight(HIGH); 
}

void loop() {
 // Read sensor parameter
 h = dht.readHumidity();
 t = dht.readTemperature();
 // Display on LCD
 lcd_display_temp_humid(t,h);
 // Send via serialport
 Serial.print(t);
 Serial.print(",");
 Serial.flush();
 // Delay for next round
 delay(2000);
}

void lcd_display_temp_humid(float temperature, float humidity){
 lcd.clear();
 lcd.print("Tempe: ");
 lcd.print(floatToString(bufferstore, temperature, 2, 5, true));
 lcd.print(" C");
 lcd.setCursor(0,1);
 lcd.print("Humid: ");
 lcd.print(floatToString(bufferstore, humidity, 2, 5, true));
 lcd.print(" %");
}

floatToString.h


// floatToString.h
//
// Tim Hirzel
// tim@growdown.com
// March 2008
// float to string
// 
// If you don't save this as a .h, you will want to remove the default arguments 
// uncomment this first line, and swap it for the next. I don't think keyword arguments compile in .pde files

//char * floatToString(char * outstr, float value, int places, int minwidth=, bool rightjustify) {
char * floatToString(char * outstr, float value, int places, int minwidth=0, bool rightjustify=false) {
 // this is used to write a float value to string, outstr. oustr is also the return value.
 int digit;
 float tens = 0.1;
 int tenscount = 0;
 int i;
 float tempfloat = value;
 int c = 0;
 int charcount = 1;
 int extra = 0;
 // make sure we round properly. this could use pow from <math.h>, but doesn't seem worth the import
 // if this rounding step isn't here, the value 54.321 prints as 54.3209

// calculate rounding term d: 0.5/pow(10,places) 
 float d = 0.5;
 if (value < 0)
 d *= -1.0;
 // divide by ten for each decimal place
 for (i = 0; i < places; i++)
 d/= 10.0; 
 // this small addition, combined with truncation will round our values properly 
 tempfloat += d;

// first get value tens to be the large power of ten less than value 
 if (value < 0)
 tempfloat *= -1.0;
 while ((tens * 10.0) <= tempfloat) {
 tens *= 10.0;
 tenscount += 1;
 }

if (tenscount > 0)
 charcount += tenscount;
 else
 charcount += 1;

if (value < 0)
 charcount += 1;
 charcount += 1 + places;

minwidth += 1; // both count the null final character
 if (minwidth > charcount){ 
 extra = minwidth - charcount;
 charcount = minwidth;
 }

if (extra > 0 and rightjustify) {
 for (int i = 0; i< extra; i++) {
 outstr[c++] = ' ';
 }
 }

// write out the negative if needed
 if (value < 0)
 outstr[c++] = '-';

if (tenscount == 0) 
 outstr[c++] = '0';

for (i=0; i< tenscount; i++) {
 digit = (int) (tempfloat/tens);
 itoa(digit, &outstr[c++], 10);
 tempfloat = tempfloat - ((float)digit * tens);
 tens /= 10.0;
 }

// if no places after decimal, stop now and return

// otherwise, write the point and continue on
 if (places > 0)
 outstr[c++] = '.';


 // now write out each decimal place by shifting digits one by one into the ones place and writing the truncated value
 for (i = 0; i < places; i++) {
 tempfloat *= 10.0; 
 digit = (int) tempfloat;
 itoa(digit, &outstr[c++], 10);
 // once written, subtract off that digit
 tempfloat = tempfloat - (float) digit; 
 }
 if (extra > 0 and not rightjustify) {
 for (int i = 0; i< extra; i++) {
 outstr[c++] = ' ';
 }
 }


 outstr[c++] = '\0';
 return outstr;
}

Till now, I am just a copier without clearly understand how things are done. I have temperature and humidity but only show one of them. The main loop of Arduino has to send the data continuously. It is not practical. The right procedure is when PC sends command to Arduino, Arduino responses. I hope to do better job next time.

PS: remember 10k pick-up resistor of DHT signal pin.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s