Semua Tentang Belajar Teknologi Digital Dalam Kehidupan Sehari - Hari

Rabu, 18 Agustus 2021

ATtiny2313 vs DHT11 - Jangan pernah pakai library arduino, kembali ke dasar koding GCC !

 


Pembahasan kali ini sudah pernah saya tulis sebelumnya 8 tahun yg lalu, dimana DHT11 merupakan sensor sejuta umat yg sangat umum dipakai untuk belajar IOT. Sensor ini memiliki sistem komunikasi serial 1 bus wire, dimana semua datanya dikirim melalui 1 buah jalur data dengan pembeda 1 dan 0 nya berdasarkan lebar pulsa atau timer dari level logicnya. Jadi untuk pemahaman dasar pembacaan sensornya dapat dibaca di sini : https://www.aisi555.com/2013/05/dht-11-sensor-suhu-dan-kelembaban-murah.html

Jadi jika ingin mengirimkan pembacaan DHT11 menuju serial com di PC, maka scriptnya lumayan memusingkan untuk dilihat, terutama dibagian pembacaan pulsanya.


Namun jangan lupa baca dulu  pembahasan pengaturan fusebit nya disini : https://www.aisi555.com/2021/08/attiny2313-vs-arduino-library-bagaimana.html


#define F_CPU 8000000UL //frek clock internal
#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h> 
#include <string.h>
#include <stdlib.h>


//rumus penentuan baudrate

#define USART_BAUDRATE 9600  // baudrate 9600 bps
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)

//deklarasi menu & tulisan .
//gunakan memori flash(PROGMEM) biar cukup


const char suhunya[] PROGMEM = " suhu : ";
const char huminya[] PROGMEM = "C - kelembaban : ";



void init_usart(void)

{

	UCSRB |= (1 << TXEN);   // kirim aja
	UCSRC |= (1 << UCSZ0) | (1 << UCSZ1);
	UBRRL = BAUD_PRESCALE;
	UBRRH = (BAUD_PRESCALE >> 8);
}


//function untuk mengirim char

void USART_Tx(unsigned char data)

{	

	while (!(UCSRA & (1<<UDRE)));{} 
	UDR = data; // Send data to the computer


}



//function untuk kirim kalimat dari flash Progmem


void kirim_text(const char *data)

{

	while (pgm_read_byte(data) != 0x00)
	USART_Tx(pgm_read_byte(data++));

}

void kirim(char *data) //kirim teks dari ram

{

	while (*data != 0x00)
	USART_Tx(*data++);

}


uint8_t hitung(void)
{

	uint8_t a,counter,hasil;

	counter=0;
	hasil=0;

	for (a=8;a>0;a--) // 8 kali tiap perhitungan
	{


		while(counter <100) // deteksi saat LOW ( tidak ada perhitungan)
		{
			_delay_us(1);
			counter++;
			if (bit_is_set(PIND, 3)) break; //tunggu sampai high dan keluar loop
		}

		counter=0;

		while(counter <100)
		{
			_delay_us(1);
			counter++; // counter mendeteksi lebar pulsa
			if (bit_is_clear(PIND, 3)) break; //jika low maka keluar dari loop
		}

		// perhitungan 8 bit decimal dengan geser-geser bit
		//jika lebih 25us =1 , kurang < 25 us = 0
		
		if(counter > 25) hasil += (1 << (a-1)) ;

		counter=0;

	}

	return hasil;


}

void baca_sensor()
{

	char dum;  // variabel sementara

	int suhu;
	int suhuu;
	int humi;
	int counter=0;

	DDRD|=(1<<PD3); //PD3 sebagai output
	_delay_ms(250);

	PORTD &=~(1<<PD3); // nolkan PD3
	_delay_ms(18); //tunggu 18 ms

	PORTD |=(1<<PD3); // naikkan PD3
	_delay_us(40); //tunggu 40us


	DDRD &=~(1<<PD3); //PD3 sebagai input

	//tunggu response dari DHT11

	while(counter <100)
	{
		_delay_us(1);
		counter++;
		if (bit_is_set(PIND, 3)) break;
	}

	counter=0;

	while(counter <100)
	{
		_delay_us(1);
		counter++;
		if (bit_is_clear(PIND, 3)) break;
	}


	//baca data setelah response, lihat script di pembahasan selanjutnya untuk routine hitung()

	//8 bit pertama ( puluhan kelembaban )
	humi=hitung();
	//8 bit kedua( satuan kelembaban ), tidak usah di baca karena nilai selalu 0 untuk DHT11
	hitung();
	//8 bit ketiga ( puluhan suhu )
	suhu=hitung();
	//8 bit keempat ( satuan suhu ), tidak usah di baca karena nilai selalu 0 untuk DHT11
	suhuu=hitung();
	
	kirim_text(suhunya);
	itoa(suhu,&dum,10);
	kirim(&dum);
	USART_Tx('.');
	itoa(suhuu,&dum,10);
	kirim(&dum);
	USART_Tx(0xF8);
	kirim_text(huminya);
	itoa(humi,&dum,10);
	kirim(&dum);
	USART_Tx('%');
	USART_Tx('\n');
	USART_Tx('\r');
	
	
	
	
}




int main(void)

{
	
	
  init_usart();

  while(1) //muter tiada henti
	{

	baca_sensor();
	_delay_ms(5000);

	}

}









Wah ..segitu panjangnya, padahal jika dilihat kembali cara pembacaan DHT11 pada arduino, cukup mengikuti library buatan adafruit yg banyak contohnya beredar di internet dan cukup hanya beberapa baris coding saja. 

Namun ini dapat menjadi masalah besar saat ATtiny2313 yang digunakan, lalu bagaimana memampatkan nya di attiny menggunakan sketch arduino ? Bayangkan pembahasan sebelunya dimana attiny full hanya dengan script yg mengerjakan komunikasi serial, jadi jika menggunakan library DHT dari adafruit yg biasa dipakai pada arduino, dijamin flash memori akan melebihi 100% . Ada lagi yg penting yaitu butuh penanganan clock yang jauh berbeda. Dan hasilnay script saya diatas tidak berjalan  seperti yg diinginkan. Jadi pengaturan clock untuk mencari pewaktu 1 microseconds sangatlah critical.



Berikut ini script Attiny vs DHT11  pada  sketch arduino  :


#define USART_BAUDRATE 9600  // baudrate 9600 bps
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)

const char suhunya[] PROGMEM = " suhu : ";
const char huminya[] PROGMEM = " C - kelembaban : ";



int DHT11_Pin = 5; // DHT11 ke pin PD3

int Humidity = 0;
int Temp = 0;
int TempComma = 0;
bool DHTError = false; // Checksum Error

// a Delay routine. Call DelayTimer(time in uSec)

void DelayTimer(long int DelayValue){
long int DelayTime = micros();
do {

}while (micros()-DelayTime < DelayValue);
}
// Main DHT Void

void DHT11(){

long int DataTime = 0;

byte Result[45];
byte DataArray = 0;
byte DataCounter = 0;
byte DHTData[4];

bool BlockDHT=false;

// Trigger Sensor (described in the Datasheet)

pinMode(DHT11_Pin,OUTPUT);
digitalWrite(DHT11_Pin,HIGH);
DelayTimer(250000); //Wait 250millisec
digitalWrite(DHT11_Pin,LOW);
DelayTimer(30000); //Wait 30millisec
digitalWrite(DHT11_Pin,HIGH);
DelayTimer(50); //Wait 50microsec
pinMode(DHT11_Pin,INPUT);
// read the Bits and put them into a Result array (It will count 42 bits. The first two one are useless due my code)

do {
if (digitalRead(DHT11_Pin) == 0 && BlockDHT == false) {BlockDHT = true;Result[DataArray]=(micros()-DataTime);DataArray++;DataTime=micros();} //If DHT pin is low, go to next Dataset
if (digitalRead(DHT11_Pin) == 1) {BlockDHT = false;} // As long as DHT pin is Hight add time in Microseconds to Result

}while((micros()-DataTime) < 150); // if DTH Sensor high for more than 150 usec, leave loop

// Asign 1 or 0 to Result variable. If more than 80uS Data as “1”
// Starting at Data set 02. First two Datasets are ignored!

for (int i=2; i< DataArray; i++) {
if (Result[i] <= 90) Result[i]=0; else Result[i]=1;

}


for (int j=0; j< 5; j++){ // redo it for the 5 Bytes (40 Databits /8 = 5)
for (int i=0; i< 8; i++) {bitWrite(DHTData[j], 7-i, Result[i+2+(j*8)]);} // Create 5 Databytes from the 40 Databits (Ignoring the 2 first Databits)

}
// check checksum }

if (DHTData[4] == (DHTData[0]+DHTData[1]+DHTData[2]+DHTData[3])){Humidity = DHTData[0];Temp = DHTData[2];TempComma = DHTData[3];DHTError=false;} else DHTError=true; //If Checksum is worng, Temp=99 (Dataset 0-3 in addition = Dataset 4 = Checksum OK)

}



  void init_usart(void)

{

  UCSRB |= (1 << TXEN);   // kirim aja
  UCSRC |= (1 << UCSZ0) | (1 << UCSZ1);
  UBRRL = BAUD_PRESCALE;
  UBRRH = (BAUD_PRESCALE >> 8);

}

 void USART_Tx(unsigned char data)

{

 

  while (!(UCSRA & (1<<UDRE)));{} // wait till transmit Data register is empty

  UDR = data; // Send data to the computer



}



//function untuk kirim kalimat



void kirim_text(const char *data)

{

  while (pgm_read_byte(data) != 0x00)

  USART_Tx(pgm_read_byte(data++));

}

void kirim(char *data)

{

  while (*data != 0x00)
  USART_Tx(*data++);

}



void setup() {
  // put your setup code here, to run once:
init_usart();

}

void loop() {
char dum;  
DHT11();
if (DHTError == false)
{ kirim_text(suhunya);
  itoa(Temp,&dum,10);
  kirim(&dum);
  USART_Tx(',');
  itoa(TempComma,&dum,10);
  kirim(&dum);
  kirim_text(huminya);
  itoa(Humidity,&dum,10);
  kirim(&dum);
  USART_Tx('%');
  USART_Tx('\n');
  USART_Tx('\r');
  } 
  else kirim("Error");


DelayTimer(1000000); //wait 1 sec
}



Wew...jadi kembali ke dasar koding GCC yuk...wong sama aja ribetnya...
Share:

0 komentar:

Posting Komentar

Kontak Penulis



12179018.png (60×60)
+628155737755

Mail : ahocool@gmail.com

Site View

Categories

555 (8) 7 segmen (3) adc (4) amplifier (2) analog (19) android (12) antares (8) arduino (26) artikel (11) attiny (3) attiny2313 (19) audio (5) baterai (5) blog (1) bluetooth (1) chatgpt (2) cmos (2) crypto (2) dasar (46) digital (11) dimmer (5) display (3) esp8266 (25) euro2020 (13) gcc (1) iklan (1) infrared (2) Input Output (3) iot (58) jam (7) jualan (12) kereta api (1) keyboard (1) keypad (3) kios pulsa (2) kit (6) komponen (17) komputer (3) komunikasi (1) kontrol (8) lain-lain (8) lcd (2) led (14) led matrix (6) line tracer (1) lm35 (1) lora (7) MATV (1) memory (1) metal detector (4) microcontroller (70) micropython (6) mikrokontroler (1) mikrokontroller (14) mikrotik (5) modbus (9) mqtt (3) ninmedia (5) ntp (1) paket belajar (19) palang pintu otomatis (1) parabola (88) pcb (2) power (1) praktek (2) project (33) proyek (1) python (7) radio (24) raspberry pi (4) remote (1) revisi (1) rfid (1) robot (1) rpm (2) rs232 (1) script break down (3) sdcard (3) sensor (2) sharing (3) signage (1) sinyal (1) sms (6) software (18) solar (1) solusi (1) tachometer (2) technology (1) teknologi (2) telegram (2) telepon (9) televisi (167) television (28) transistor (2) troubleshoot (3) tulisan (93) tutorial (108) tv digital (6) tvri (2) vu meter (2) vumeter (2) wav player (3) wayang (1) wifi (3)

Arsip Blog

Diskusi


kaskus
Forum Hobby Elektronika