Önceki yazıda USART çevre biriminin özelliklerinden ve transmitter reciever olarak konfigürasyonlarının yapılandırılmasından bahsedildi. Bu uygulamada ise HC-05 bluetooth sensörü ile STM32 kartı harbeleştirip bir adet NTC sıcaklık sensörü ile ortam sıcaklığının kontrolü gerçekleştirilip, bluetooth serial terminal ekranında sıcaklık çıktıları görülmüş ve ardından sıcaklık belli değer üstünde ise uyarı sistemi olarak led yakılmıştır.
Kullanılan termistör 10K NTC'dir. NTC (Negative Temperature Coefficient), Termistör veya Isıl direnç, bulunduğu ortamın veya temas ettiği yüzeyin sıcaklığı arttıkça elektriksel direnci azalan devre elemanıdır. NTC direnci ısıyla kontrol edilen bir direnç türüdür. PTC türü de vardır. Bu türü ise NTC’nin tam tersi şekilde ısı arttıkça elektriksel direnci artan bir elemandır.
Telefona indirilebilen bluetooth çıktılarını görmeyi sağlayan uygulamalarda ya da bilgisayarlar için olan serial ekranlardan program çıktıları görülebilmektedir. Bu uygulamada Windows için olan bluetooth terminal ekranı kullanılmıştır. Devre bağlantısı yapıldıktan sonra bluetooth bağlantısı için cihazlar taranır ve HC-05 eşleştirilir. Eşleşme için şifre gerekiyorsa 1234 girilir ve ardından serial terminal üzerinden HC-05 seçilerek bağlantı gerçekleştirilir.
Daha sonra St-Link Utility üzerinden kod karta gönderilir, sıcaklık değerleri görülmeye başlar. NTC'ler çok hassas olmadıkları için dereceler değişkenlik gösterebilmektedir, NTC ısıtılarak sıcaklık artışı da gözlemlenebilir. Son olarak sıcaklık 40 dereceyi geçtiğinde ise uyarı olarak ledin yandığı görülmektedir.
Malzemeler, Devre Şeması ve Kodlar:
STM32VL Discovery Board
Led
HC-05 Bluetooth Sensörü
10K direnç
10K NTC termistör
Bread Board
Bağlantı Kabloları
#include "stm32f10x.h" // Device header
#include "delay.h"
#include "math.h" // mat kütüphanesindeki fonksiyonlar için eklenmistir
#include <stdio.h> // sprintf fonksiyonu için eklenmistir
// bluetoothla ntcden alinan sicaklik degerini ekrana göndermek
//sicaklik belli degerin ustundeyse lede sinyal gider
void gpioConfig(); // pin konfigürasyonlari
void usartConfig(); // usart tx rx konfigürasyonu
void verigonder(char *string); // karttan gelecek bilginin bluetooth serial ekraninda gosterilmesi için
void adcConfig(); // adc konfigurasyonu
double termistor(uint16_t adcDegeri); // adc'den okunan ham ntc degerini gercek sicaklik degerlerine donusturmek icin olusturulan fonksiyon
uint16_t OkunanAdcDegeri(); // ntc sicaklik sensorunden okuma yapilacak, ham degerler elde edilecek olan fonksiyon
uint16_t adcDegeri=0; // ilk adcden okunan ham veri 0 olsun
uint16_t sicaklik=0; // ilk sicaklik 0 olsun
char message[30]=""; // bluetooth seri ekranina kart tarafindan gonderilecek mesaj en fazla 30 karakterli bir array
int main (){
gpioConfig();
usartConfig();
adcConfig();
DelayInit();
while(1){
adcDegeri=OkunanAdcDegeri(); // ham adc verileri aliniyor
sicaklik=termistor(adcDegeri); // ham veriler termistor fonksiyonuna gonderiliyor, gercek degerler için
// sprintf(message, "Sicaklik %d derece\r\n", sicaklik); // sadece sicakliklar gorulmek isteniyorsa
// verigonder(message);
// delayms(1000);
if (sicaklik > 40){ // sicaklik 40 derece üstü olunca PB0'a bagli led yanacak
GPIO_SetBits(GPIOB,GPIO_Pin_0);
sprintf(message,"sicaklik 40 derece ustu %d derece\r\n",sicaklik);
verigonder(message);
}
else { // sicaklik 40 derece altiysa led yanmayacak
GPIO_ResetBits(GPIOB,GPIO_Pin_0);
sprintf(message,"sicaklik 40 derece alti %d derece\r\n",sicaklik);
verigonder(message);
}
delayms(1000);
}
}
void gpioConfig(){
GPIO_InitTypeDef GPIOInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); // HC05 Rx-Tx pinleri ve termistör okumasi için PA9 ve PA10 PA0 kullanildi clock hatti aktif ediliyor
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);// led için PB0 kullanildi B portu clock hatti aktif ediliyor
GPIOInitStructure.GPIO_Mode=GPIO_Mode_AF_PP; // tx için
GPIOInitStructure.GPIO_Pin=GPIO_Pin_9;
GPIOInitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIOInitStructure);
GPIOInitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING; // rx için
GPIOInitStructure.GPIO_Pin=GPIO_Pin_10;
GPIOInitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIOInitStructure);
GPIOInitStructure.GPIO_Mode=GPIO_Mode_Out_PP; // led
GPIOInitStructure.GPIO_Pin=GPIO_Pin_0;
GPIOInitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIOInitStructure);
GPIOInitStructure.GPIO_Mode=GPIO_Mode_AIN; // termistör
GPIOInitStructure.GPIO_Pin=GPIO_Pin_0;
GPIOInitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIOInitStructure);
}
void usartConfig(){
USART_InitTypeDef USARTInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); // A portunda Usart1 var clock hatti aktif edilmelidir
USARTInitStructure.USART_BaudRate=9600; // veri iletim hizi olan baudrate 9600 seçiliyor
USARTInitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None; // RS-232, RS-485, RS 282 gibi iletisim strandartlari kullaniliyorsa hardware flow control aktif edilmelidir. Burda kullanilmiyor none.
USARTInitStructure.USART_Mode=USART_Mode_Tx | USART_Mode_Rx; // Tx ve Rx mode aktif edildi, sadece Txmode da aktif edilebilir çünkü karttan veri aliniyor, veri gitmiyor
USARTInitStructure.USART_Parity=USART_Parity_No; // paritiy kontrolü yaplmiyor
USARTInitStructure.USART_StopBits=USART_StopBits_1; // 1 bit durdurma biti olarak seçilmistir
USARTInitStructure.USART_WordLength=USART_WordLength_8b; //// 8 bitlik veri iletimi
USART_Init(USART1, &USARTInitStructure); // USART1 ayarlamalari yapildigi bildiriliyor
USART_Cmd(USART1,ENABLE);
}
void verigonder(char *string){ //karttan gelecek mesajin fonksiyonu. mesajin hepsi gitmesi için sr registeri kontrol ediliyor
while(*string){
while(!(USART1->SR & 0x00000040));
USART_SendData(USART1,*string);
*string++;
}
}
void adcConfig(){
ADC_InitTypeDef ADCInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE); // PA0 için ADC1den okuma yapilabiliyor. ve aktif edildi
ADCInitStructure.ADC_ContinuousConvMode=ENABLE; // okuma sürekli yapilacagi icin enable edildi
ADCInitStructure.ADC_DataAlign=ADC_DataAlign_Right; // veriler saga yasli olacak
ADCInitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None; //yazilim kaynakli bir trigger kullanilmayacak
ADCInitStructure.ADC_Mode=ADC_Mode_Independent;
ADCInitStructure.ADC_NbrOfChannel=1; //1 tane adc kanalini okunacak
ADCInitStructure.ADC_ScanConvMode=DISABLE; //Eger birden fazla kanal örneklemek istenseydi, ‘enable’ seçenegi seçilecekti
ADC_Init(ADC1, &ADCInitStructure); // adc konfigürasyonu yapildigi bildiriliyor
ADC_Cmd(ADC1,ENABLE);
}
uint16_t OkunanAdcDegeri(){
ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5); //adc 1in chanannel 0'indan okuma yapiliyor, 1 adc okumasi, ve hangi siklikla okuma yapilacak
ADC_SoftwareStartConvCmd(ADC1,ENABLE);
while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET); // okuma devam ediyorsa burda kalsin
return ADC_GetConversionValue(ADC1); // okuma bitince degeri döndürsün
}
double termistor(uint16_t adcDegeri){ // adcnin ham verisi burda isleme giriyor. Kart çözünürlügüne göre bu islemler degisebiliyor
double temp;
temp = log(((40950000 / adcDegeri) - 10000));
temp = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * temp * temp)) * temp);
temp= temp - 273.15;
return temp;
}
Comentarios