Android Üzerinden Dc Motor Hız ve Yön Kontrolü (STM32F4 Discovery)

Başlatan seyityildirim, 20 Aralık 2016, 18:40:50

seyityildirim

Kullanılan malzemeler

Stm32f4 Discovery kartı
HC-05 Bluetooth modül
L298N motor sürücü
12 V'luk batarya
Android destekli bir telefon
Bağlantı kabloları


Bağlantılar

Bluetooth            Discovery

Rx                           Tx  (PB6)

Tx                           Rx  (PB7)

GND                      GND

VCC                       3.3 V

L298N                 Discovery

IN1                        PD12

IN2                       PD13



L298N OUT1 uçlarına DC motor takılır. 12V luk bataryanın uçları da L298N in 12V ve GND uçlarına takılır. Aynı GND ucu Discovery GND si ile birleştirilmelidir.

Keil'de yazılan kodlar aşağıdadır. Anlamadığınız yerler olursa cevaplamaya çalışırım.



#include "stm32f4xx.h" // Device header
#include "stm32f4xx_conf.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>


#define peryod 8399
#define MAX_STRLEN 12 // this is the maximum string length of our string in characters

char received_string[MAX_STRLEN+1]; // this will hold the recieved string
int veri;

uint16_t PWM_Duty 0;
uint16_t PWM_Freq 10000;

// Funtion Prototypes

void PWM_SetDutyCycle(TIM_TypeDefTIMxuint8_t Dutyuint8_t OCx);
void init_USART1(uint32_t baudrate);
void USART_puts(USART_TypeDefUSARTxvolatile char *s);
void USART1_IRQHandler(void);
void PWM_Config(void);

int main()
{
 
// Enable HSE clock
 
RCC_HSEConfig(RCC_HSE_ON);
 
// Wait for clock to stabilize
 
while (!RCC_WaitForHSEStartUp());

init_USART1(9600); // initialize USART1 @ 38400 baud
 
PWM_Config();
 while(
1);
}

void init_USART1(uint32_t baudrate)
{
 
 
GPIO_InitTypeDef GPIO_InitStruct// TX ve RX olarak kullanacagimiz GPIO pinleri için
 
USART_InitTypeDef USART_InitStruct// USART1 için
 
NVIC_InitTypeDef NVIC_InitStructure// Kesmeleri ayarlamak için
 
 /* USART1 için APB2 clock u aktif edilir 
 * sadece USART1 ve USART6 APB2 ye baglidir.
 * diger USART lar APB1 clock hattina baglidir
 */
 
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1ENABLE);
 
 
/* USART1 tarafindan TX için PB6 pini, RX için PB7 pini kullanilacak
 * Bu pinlerin bulundugu GPIO hattinin clock u aktif edilir.
 */
 
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOBENABLE);
 
 
/* This sequence sets up the TX and RX pins 
 * so they work correctly with the USART1 peripheral
 */
 
GPIO_InitStruct.GPIO_Pin GPIO_Pin_6 GPIO_Pin_7// Pin 6 (TX) ve Pin7 (RX) olarak kullanilacak
 
GPIO_InitStruct.GPIO_Mode GPIO_Mode_AF// Bu pinler alternetif fonksiyon olarak tanimlandi ki USART buraya ulasabilsin
 
GPIO_InitStruct.GPIO_Speed GPIO_Speed_50MHz// IO nin hizini belirler ve baud rate ile alakasi yoktur
 
GPIO_InitStruct.GPIO_OType GPIO_OType_PP// Çikis Push-pull olarak ayarlandi
 
GPIO_InitStruct.GPIO_PuPd GPIO_PuPd_UP// Pull-up direnci aktif edildi.
 
GPIO_Init(GPIOB, &GPIO_InitStruct); 
 
 
/* RX ve TX pimleri simdi AF'ye baglidir, böylece USART1 pinlerin kontrolünü devralabilir
 */
 
GPIO_PinAFConfig(GPIOBGPIO_PinSource6GPIO_AF_USART1); //
 
GPIO_PinAFConfig(GPIOBGPIO_PinSource7GPIO_AF_USART1);
 
 
/* USART_InitStruct USART1'in özelliklerini tanimlamak için kullanilacak
 */
 
USART_InitStruct.USART_BaudRate baudrate
 
USART_InitStruct.USART_WordLength USART_WordLength_8b;
 
USART_InitStruct.USART_StopBits USART_StopBits_1;
 
USART_InitStruct.USART_Parity USART_Parity_No
 
USART_InitStruct.USART_HardwareFlowControl USART_HardwareFlowControl_None
 
USART_InitStruct.USART_Mode USART_Mode_Tx USART_Mode_Rx;
 
USART_Init(USART1, &USART_InitStruct); 
 
 
 
/* Here the USART1 receive interrupt is enabled
 * and the interrupt controller is configured 
 * to jump to the USART1_IRQHandler() function
 * if the USART1 receive interrupt occurs
 */ 
 
USART_ITConfig(USART1USART_IT_RXNEENABLE); // USART1 gelen veri kesmesi aktif edilir
 
 
NVIC_InitStructure.NVIC_IRQChannel USART1_IRQn// USART1 kesmesi ayarlancak.
 
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority 1;// 
 
NVIC_InitStructure.NVIC_IRQChannelSubPriority 1// 
 
NVIC_InitStructure.NVIC_IRQChannelCmd ENABLE// the USART1 interrupts are globally enabled
 
NVIC_Init(&NVIC_InitStructure); 
 
 
USART_Cmd(USART1ENABLE); // sonuç olarak USART1 donanimi aktif edildi
}

void USART1_IRQHandler(void)
{
 
// check if the USART1 receive interrupt flag was set
 
if( USART_GetITStatus(USART1USART_IT_RXNE) )
 {
 static 
uint8_t cnt 0// this counter is used to determine the string length
 
char t USART1->DR// the character from the USART1 data register is saved in t
 
 /* check if the received character is not the LF character (used to determine end of string) 
 * or the if the maximum string length has been been reached 
 */
 
if( (!= '\n') && (cnt MAX_STRLEN) ){ 
 
received_string[cnt] = t;
 
cnt++;
 }
 
 else{ 
// otherwise reset the character counter and print the received string
 
cnt 0;
 
 }
 
cnt=0;
 
///////////////////////////////////////////////////////////////////////
 
veri=received_string[0]; 
 if (
veri=='a')
 {
 
PWM_SetDutyCycle(TIM4,0,1);
 
PWM_SetDutyCycle(TIM4,0,2);
 }
 else if (
veri=='b')
 {
 
PWM_SetDutyCycle(TIM4,25,1);
 
PWM_SetDutyCycle(TIM4,0,2); 
 }
 else if (
veri=='c')
 {
 
PWM_SetDutyCycle(TIM4,50,1);
 
PWM_SetDutyCycle(TIM4,0,2); 
 }
 else if (
veri=='d')
 {
 
PWM_SetDutyCycle(TIM4,75,1);
 
PWM_SetDutyCycle(TIM4,0,2); 
 }
 else if (
veri=='e')
 {
 
PWM_SetDutyCycle(TIM4,100,1);
 
PWM_SetDutyCycle(TIM4,0,2); 
 }
 else if (
veri=='f')
 {
 
PWM_SetDutyCycle(TIM4,0,1);
 
PWM_SetDutyCycle(TIM4,0,2); 
 }
 else if (
veri=='g')
 {
 
PWM_SetDutyCycle(TIM4,0,1);
 
PWM_SetDutyCycle(TIM4,25,2); 
 }
 else if (
veri=='h')
 {
 
PWM_SetDutyCycle(TIM4,0,1);
 
PWM_SetDutyCycle(TIM4,50,2); 
 }
 else if (
veri=='k')
 {
 
PWM_SetDutyCycle(TIM4,0,1);
 
PWM_SetDutyCycle(TIM4,75,2); 
 }
 else if (
veri=='l')
 {
 
PWM_SetDutyCycle(TIM4,0,1);
 
PWM_SetDutyCycle(TIM4,100,2); 
 }
 
 }
 
USART_ClearITPendingBit(USART1USART_IT_RXNE);
}
void PWM_SetDutyCycle(TIM_TypeDefTIMxuint8_t Dutyuint8_t OCx)
{
 switch(
OCx)
 {
 case 
1TIMx->CCR1 = (Duty peryod) / 100; break;
 case 
2TIMx->CCR2 = (Duty peryod) / 100; break;
 case 
3TIMx->CCR3 = (Duty peryod) / 100; break;
 case 
4TIMx->CCR4 = (Duty peryod) / 100; break;
 }
}

void PWM_Config(void)
{
 
GPIO_InitTypeDef GPIO_InitStructure;
 
TIM_TimeBaseInitTypeDef TIM_BaseStruct;
 
TIM_OCInitTypeDef TIM_OCStruct;
 
 
 
/* Clock for GPIOD */
 
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIODENABLE);
 
/* Enable clock for TIM4 */
 
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4ENABLE);

GPIO_InitStructure.GPIO_Pin GPIO_Pin_12 GPIO_Pin_13;
 
GPIO_InitStructure.GPIO_OType GPIO_OType_PP;
 
GPIO_InitStructure.GPIO_PuPd GPIO_PuPd_NOPULL;
 
GPIO_InitStructure.GPIO_Mode GPIO_Mode_AF;
 
GPIO_InitStructure.GPIO_Speed GPIO_Speed_100MHz;
 
GPIO_Init(GPIOD, &GPIO_InitStructure);
 
 
/* Alternating functions for pins */
 
GPIO_PinAFConfig(GPIODGPIO_PinSource12GPIO_AF_TIM4);
 
GPIO_PinAFConfig(GPIODGPIO_PinSource13GPIO_AF_TIM4);
 
 
TIM_BaseStruct.TIM_Prescaler 0;
 
TIM_BaseStruct.TIM_CounterMode TIM_CounterMode_Up;
 
TIM_BaseStruct.TIM_Period peryod/* 10kHz PWM */
 
TIM_BaseStruct.TIM_ClockDivision TIM_CKD_DIV1;
 
TIM_BaseStruct.TIM_RepetitionCounter 0;
 
 
TIM_TimeBaseInit(TIM4, &TIM_BaseStruct);
 
/* Start count on TIM4 */
 
TIM_Cmd(TIM4ENABLE);
 
 
TIM_OCStruct.TIM_OCMode TIM_OCMode_PWM2;
 
TIM_OCStruct.TIM_OutputState TIM_OutputState_Enable;
 
TIM_OCStruct.TIM_OCPolarity TIM_OCPolarity_Low;
 
TIM_OCStruct.TIM_Pulse 0;
 
 
TIM_OC1Init(TIM4, &TIM_OCStruct);
 
TIM_OC1PreloadConfig(TIM4TIM_OCPreload_Enable);
 
 
TIM_OCStruct.TIM_Pulse =0
 
TIM_OC2Init(TIM4, &TIM_OCStruct);
 
TIM_OC2PreloadConfig(TIM4TIM_OCPreload_Enable);
}
A



App inventor programında oluşturulan Android arayüz için kod blokları ve videosu için

https://artibesvolt.wordpress.com/2016/12/20/android-uzerinden-dc-motor-hiz-ve-yon-kontrolu-stm32f4-discovery/


Zoroaster

Seytan deliginden kacti.

muhendisbey

Burada motordan geri besleme göremedim. RPM değeri motorun satıcısından alınmış gibi geldi. Hall effect ve mini mıknatıs iş görebilir. Yada yarıklı metal disk (örneğin gazoz kapağı)+indüktif sensör. Onun dışında birçok arkadaşın işine yarayacak, android-Bluetooth UART-stm32f4-pwm çözümü olmuş. Tebrikler.
Zulmü alkışlayamam, zalimi asla sevemem; Gelenin keyfi için geçmişe kalkıp sövemem.

seyityildirim

Alıntı yapılan: muhendisbey - 20 Aralık 2016, 23:20:31
Burada motordan geri besleme göremedim. RPM değeri motorun satıcısından alınmış gibi geldi. Hall effect ve mini mıknatıs iş görebilir. Yada yarıklı metal disk (örneğin gazoz kapağı)+indüktif sensör. Onun dışında birçok arkadaşın işine yarayacak, android-Bluetooth UART-stm32f4-pwm çözümü olmuş. Tebrikler.

Belirtmeyi unutmuşum hocam kullanılan motor 2500 rpm. Geri besleme kullanılmadan yapıldı dediğiniz gibi.

Yasal Uyarı: Picproje.org sitemizde 5651 sayılı kanunun 8. maddesine ve T.C.Knın 125. maddesine göre tüm üyelerimiz yaptıkları paylaşımlardan kendileri sorumludur. Picproje.org hakkında yapılacak tüm hukuksal şikayetleri İletişim sayfamızdan bize bildirdikten en geç 3 (üç) iş günü içerisinde ilgili kanunlar ve yönetmelikler çerçevesinde tarafımızca incelenerek gereken işlemler yapılacak ve site yöneticilerimiz tarafından bilgi verilecektir.