SERVO MOTOR SG90 controlo por PWM

Olá,

Esta demorado o projecto do carro autónomo 🙂

Para esse trabalho vamos precisar de ter um controlo de distâncias, usarei um sonar que medirá as distâncias disponíveis auxiliado com a rotação de um servo motor (SG 9g) controlado por PWM.

micro-servo-motor-sg90-1

o sonar neste pequeno exemplo esta configurado para executar o PWM do SG9g entre (0-30).

O datasheet infroma que poderemos usar a rotação de 0-180º.

Oportunamente colocarei neste espaço a forma de configurar o timer com PWM para controlo do SG 9g,

/*
*MicroServo9g.c
*Created: 22-09-2017
*Author: Norlinux
*http://www.microelectronic.pt
*https://www.facebook.com/MundoDosMicrocontroladores/
*http://maquina.96.lt
*Released under GPLv3.
*Please refer to LICENSE file for licensing information.
*which can be found at http://www.gnu.org/licenses/gpl.txt
*/
#include <avr/io.h>
#include <avr/interrupt.h>
#include
#define F_CPU 8000000UL
#include <util/delay.h>
#include "lcd/lcd_lib.h"
#include "Functions.h"
volatile unsigned char vucUp = 0;
volatile uint32_t uiTimerCounter = 0;
volatile unsigned char vucStartSonar = 0;
volatile long vlResult = 0;
uint16_t uiValorMax=0, uiValor[3]={};
uint16_t uiValorEsq=0, uiValorDir=0, uiValor0=0;
Servo Servo9g={0,0}; // Inicio da Estrutura
void SendTrigger();
void ServerMotor(Servo *Servo9g);
// timer overflow interrupt, each time when timer value passes 255 value
SIGNAL(TIMER0_OVF_vect)
{
if (vucUp) { // voltage rise was detected previously
uiTimerCounter++; // count the number of overflows
// dont wait too long for the sonar end response, stop if time for measuring the distance exceeded limits
uint32_t ticks = uiTimerCounter * 256 + TCNT0;
uint32_t max_ticks = (uint32_t)MAX_RESP_TIME_MS * INSTR_PER_MS; // this could be replaced with a value instead of multiplying
if (ticks > max_ticks) {
// timeout
vucUp = 0; // stop counting timer values
vucStartSonar = 0; // ultrasound scan done
vlResult = -1; // show that measurement failed with a timeout (could return max distance here if needed)
}
}
}
SIGNAL(INT1_vect)
{
if (vucStartSonar) { //accept interrupts only when sonar was started
if (vucUp == 0) { // voltage rise, start time measurement
vucUp = 1;
uiTimerCounter = 0;
TCNT0 = 0; // reset timer counter
} else {
// voltage drop, stop time measurement
vucUp = 0;
// convert from time to distance(millimeters): d = [ time_s * 340m/s ] / 2 = time_us/58
vlResult = (uiTimerCounter * 256 + TCNT0) / (58 * INSTR_PER_US);
vucStartSonar = 0;
}
}
}
int main(void)
{
char cBuffer[16]={};
HW_Init();
LCDinit();
while(1)
{
if (vucStartSonar == 0) SendTrigger();
_delay_ms(10);
sprintf(cBuffer,"Dist %04ld",vlResult);
LCDprintXY(cBuffer,4,0);
if (vlResult> 0 && vlResult <30) { INIT_TIMER3; ServerMotor(&Servo9g); } else STOP_TIMER3; } } void SendTrigger() { TRIGGER_PIN_SET_BAIXO(Trigger_Port,TRIG); _delay_us(1); TRIGGER_PIN_SET_ALTO(Trigger_Port,TRIG); vucStartSonar = 1; // sonar launched _delay_us(10); TRIGGER_PIN_SET_BAIXO(Trigger_Port,TRIG); _delay_us(1); } void ServerMotor(Servo *Servo9g) { ServoPosicao = Menos90Graus; Wait(); if (vucStartSonar == 0) SendTrigger(); uiValorEsq = vlResult; ServoPosicao = ZeroGraus; Wait(); if (vucStartSonar == 0) SendTrigger(); uiValor0 = vlResult; if (uiValorEsq>uiValor0)
{uiValorMax=uiValorEsq; Servo9g->Posicao=Pos_Esq;}
else
{uiValorMax=uiValor0; Servo9g->Posicao=Pos_Zer;}
ServoPosicao = Mais90Graus;
Wait();
if (vucStartSonar == 0) SendTrigger();
uiValorDir=vlResult;
if (uiValorMax<uiValorDir) {uiValorMax=uiValorDir; Servo9g->Posicao=Pos_Dir;}

}

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google

Você está comentando utilizando sua conta Google. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s