Daha önce burada DHT11’in C kodları ile nasıl okunacağını anlatmıştım. Şimdi de bu kodları biraz daha geliştirip, okunan sıcaklık ve nem değerlerini bir MySQL tablosuna kaydedeceğiz.

Tablomuzun yapısı şöyle:

CREATE TABLE `logs` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`date` int(11) DEFAULT NULL,
`temp` int(255) DEFAULT NULL,
`rh` int(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1;

Veritabanı tablosunu oluşturduktan sonra aşağıdaki paketlerin sistemde yüklü olduğu teyit edin. Yüklemek için apt-get komutunu kullanabilirsiniz:

  • mysql: MySQL client programs and shared library
  • mysqlclient: Backlevel MySQL shared libraries (old libs)
  • mysql-devel: Files for development of MySQL applications (a must have)
  • mysql-server: Mysql server itself
  • gcc, make and other development libs: GNU C compiler

algilayici.h  kütüphanesinden bahsetmek gerekirse; DHT11’i okuyan kodu dht11.h isimli ayrı bir dosyaya kaydettim. Böylece diğer sensörleri de gerektiğinde include ile ana programa dahil edebileceğiz. dht11.h kodunda, DHT11 sensörünü bağladığınız wiringPi numarasını doğru tanımlamaya dikkat edin, varsayılan olarak önceki yazımda da kullandığım 7 numaralı wiringPi pinini kullanmaya devam ettim.

dht11.h: DHT11 sıcaklık ve nem sensörünü okuyan C kodları

/*
* Simple test program to test the wiringPi functions
* DHT11 test
*/
#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define MAXTIMINGS 85
#define DHTPIN 7
int dht11_dat[5] = { 0, 0, 0, 0, 0 };
int read_dht11_dat()
{
uint8_t laststate = HIGH;
uint8_t counter = 0;
uint8_t j = 0, i;
dht11_dat[0] = dht11_dat[1] = dht11_dat[2] = dht11_dat[3] = dht11_dat[4] = 0;
/* pull pin down for 18 milliseconds */
pinMode( DHTPIN, OUTPUT );
digitalWrite( DHTPIN, LOW );
delay( 18 );
/* then pull it up for 40 microseconds */
digitalWrite( DHTPIN, HIGH );
delayMicroseconds( 40 );
/* prepare to read the pin */
pinMode( DHTPIN, INPUT );
/* detect change and read data */
for ( i = 0; i < MAXTIMINGS; i++ )
{
counter = 0;
while ( digitalRead( DHTPIN ) == laststate )
{
counter++;
delayMicroseconds( 1 );
if ( counter == 255 )
{
break;
}
}
laststate = digitalRead( DHTPIN );
if ( counter == 255 )
break;
/* ignore first 3 transitions */
if ( (i >= 4) && (i % 2 == 0) )
{
/* shove each bit into the storage bytes */
dht11_dat[j / 8] <<= 1;
if ( counter > 16 )
dht11_dat[j / 8] |= 1;
j++;
}
}
/*
* check we read 40 bits (8bit x 5 ) + verify checksum in the last byte
* print it out if data is good
*/
if ( (j >= 40) &&
(dht11_dat[4] == ( (dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3]) & 0xFF) ) )
{
//printf( "Sicaklik = %d.%d *C Nem = %d.%d %%\n",
//dht11_dat[2], dht11_dat[3], dht11_dat[0], dht11_dat[1] );
return 1;
}else {
//printf( "Veri alinamadi, geciliyor\n" );
return 0;
}
}

algilayici.c ana programımızın yer aldığı dosyamız. Dosyanın tanım kısmında yer alan veritabanı adı ve ve kullanıcı bilgilerini kendinize göre düzenlemeyi unutmayın. Kodları incelerseniz her saniye okunan sıcaklık ve nem verisi sadece bir önceki okumadan farklı ise veritabanına kaydediliyor. Böylece veritabanının gereksiz yere veri ile dolmasının önüne geçmiş oluyoruz.

algilayici.c Ana programımızın C kaynak dosyası

#include <mysql.h>
#include <stdio.h>
#include <time.h>
#include "dht11.h"
MYSQL *conn;
int mysql_baglan(void) {
MYSQL_RES *res;
MYSQL_ROW row;
// Veritabani parametreleri
char *server = "localhost";
char *user = "root";
char *password = "root";
char *database = "sensor";
// Mysql hazirla
conn = mysql_init(NULL);
if (conn == NULL)
{
fprintf(stderr, "%s\n", mysql_error(conn));
return 0;
}
// Veritabanina baglan
if (!mysql_real_connect(conn, server, user, password, database, 0, NULL, 0)) {
fprintf(stderr, "%s\n", mysql_error(conn));
return 0;
}
return 1;
}
int main(void) {
char sql[100];
int last_temp, last_rh;
int timestamp;
// Veritabanı baglantisini kur
if (!mysql_baglan()) {
printf("MySQL connection error!");
exit(3306);
}
// wiringPi'yi hazirla
if ( wiringPiSetup() == -1 ) {
printf("wiringPiSetup error!");
exit(3307);
}
// Sonsuz donguye gir
while ( 1 ) {
// -----------------------------
// DHT11 sensorunu oku
// -----------------------------
if (read_dht11_dat()) {
// Sicalik veya nem degismis mi?
if ((last_temp != dht11_dat[2]) || (last_rh != dht11_dat[0])) {
// SQL sorgusunu calistir
sprintf (sql, "insert into logs (date, temp, rh) values (%d, %d,%d)", (int)time(NULL), dht11_dat[2], dht11_dat[0]);
printf("%s\n", sql);
if (mysql_query(conn, sql)) {
fprintf(stderr, "%s\n", mysql_error(conn));
}
last_temp = dht11_dat[2];
last_rh = dht11_dat[0];
}
}
// Tekrar okumak icin bekle
delay(1 * 1000 );
} 
return 0;
}

Kodu derleyip çalıştırmak için derle.sh adında bir betik oluşturdum. Betiğin içeriği şöyle:

gcc -o algilayici $(mysql_config --cflags) algilayici.c $(mysql_config --libs) -l wiringPi
chmod 755 algilayici
./algilayici

Betiği ./derle.sh komutu vererek çalıştırdığınızda aşağıdaki gibi bir ekran görüntüsü ile karşılaşacaksınız.

dht11_mysql_derleme

Kodu bir süre çalıştırdığınızda aşağıdaki gibi bir veri listesine sahip olacaksınız.

dht11_mysql

Kodu sürekli olarak arka planda çalıştırmak için ./algilayici & komutunu vererek arka plana atın (& ampersant işareti programı interaktif konsoldan ayırıp geri planda çalıştırır)

Burada anlattığım konuya ait tüm dosyaları indirmek için aşağıdaki indirme bağlantısını kullanabilirsiniz.

E-Kitap: Türkiye de Dijital Gözetim (502 indirme)

 Hata Ayıklama (Şubat 2015)

Algilayici’nin bu sürümü hatalara karşı pek dayanıklı değil. Daha da geliştirilmesi gerektiğini belirtmem gerekiyor. Özellikle programı arka planda çalıştırıyorsanız muhtemel program çökmelerinden ve nedenlerinden haberiniz olamayacaktır.

fprintf ile stderr çıktısına yazılan hata mesajlarını kayıt altına alabilirsiniz. Böylece konsola geri döndüğünüzde olası çökmenin nedeni hakkında elinizde bir veri olacaktır. Algılayıcı programı tarafından stderr çıktısına yönlendirilen mesajları almak için programı aşağıdaki şekilde çalıştırarak kullanabilirsiniz.

./algilayici  > sensor.txt 2> sensor_err.txt &

sensor.txt dosyasında ekrana yazılan SQL satırları, sensor_err.txt dosyasında ise hata mesajları kayıt alına alınacaktır. Tahmin edebileceğiniz gibi 2> belirteci, stderr hata çıktısını belirtilen dosyaya yönlendirmektedir. Hem standart çıktıları hem de hata çıktılarını aynı dosyaya yönlendirmek isterseniz aşağıdaki komut satırı numarasını kullanabilirsiniz.

./algilayici > sensor.txt 2>&1

Kaynaklar:

http://www.cyberciti.biz/tips/linux-unix-connect-mysql-c-api-program.html
http://www.cyberciti.biz/faq/linux-redirect-error-output-to-file/

2 YORUMLAR

CEVAP VER