Go Down

Topic: Motor de passos + driver (código para girar em graus) (Read 2224 times) previous topic - next topic

Deiwys

Bom dia galera, testei um monte de códigos no meu motor de passos e não to conseguindo fazer ele rodar em graus, conforme eu preciso, gostaria de fazer ele girar 360 graus e parar.

Alguém teria algum exemplo ou código funcionando pra mim poder usar e fazer alguns testes aqui?

comprei esse motor aqui, aqui mesmo no DX:

28YBT-48 Stepper Motor with ULN2003 Driver (DC 5V)
http://dx.com/p/28ybt-48-stepper-motor-with-uln2003-driver-dc-5v-126409

valeu

bubulindo

de quantos passos é o motor???

onde é que os códigos falham?
Eu não sou o teu criado. Se respondo no fórum é para ajudar todos mediante a minha disponibilidade e disposição. Responder por mensagem pessoal iria contra o propósito do fórum e por isso evito-o.
Se realmente pretendes que eu te ajude por mensagem pessoal, então podemos chegar a um acordo e contrato onde me pagas pela ajuda que eu fornecer e poderás então definir os termos de confidencialidade do meu serviço. De forma contrária toda e qualquer ajuda que eu der tem de ser visível a todos os participantes do fórum (será boa ideia, veres o significado da palavra fórum).
Nota também que eu não me responsabilizo por parvoíces escritas neste espaço pelo que se vais seguir algo dito por mim, entende que o farás por tua conta e risco.

Dito isto, mensagens pessoais só se forem pessoais, ou seja, se já interagimos de alguma forma no passado ou se me pretendes convidar para uma churrascada com cerveja (paga por ti, obviamente).

Mortis

Quantos passos você esta dando para ter 360? Pela especificação, se entendi, você deve fazer esse cálculo: 360/(5,625*1/64) = 4096

Pois cada passo é (5,625*1/64) = 0,087890625 de 360 graus. então você precisa de 4096 passos para 360 graus.

Ah, sim, e esse motor não é 28YBT-48, mas sim 28YBJ-48 ;)


Deiwys

Acabei chegando nesse código aqui, consigo através da variavel Steps2Take  =  2048 dar uma volta completa, 1024 da meia volta, 4096 duas voltas e por ai vai... só fiquei meio na duvida sobre o que realmente faz as variaveis STEPS e setSpeed, o STEPS se for muito alta nao roda o motor e o setSpeed na verdade só gostaria de saber até que valor posso botar.. se botar muito alto nao roda tb.. 300 é meio um valor máximo pro meu motor como notei nos testes que fiz.. mas enfim, com esse código ja vou conseguir fazer o que eu pretendo :)

abraço

Code: [Select]

#include <Stepper.h>

#define STEPS  100

Stepper small_stepper(STEPS, 8, 10, 9, 11);
int  Steps2Take;

void setup() {
 small_stepper.setSpeed(300);  
}

void loop() {
 Steps2Take  =  2048;
 small_stepper.step(Steps2Take);
 delay(1000);
}

Mortis

#4
Jul 15, 2013, 02:53 am Last Edit: Jul 15, 2013, 02:59 am by Mortis Reason: 1
Como você esta usando a propriedade de uma livraria, somente ela pode te dizer ;)

Abra o arquivo Stepper.cpp da livraria, verá que a velocidade é determinada pela função abaixo:
Code: [Select]

void Stepper::setSpeed(long whatSpeed)
{
 this->step_delay = 60L * 1000L / this->number_of_steps / whatSpeed;
}


O que ocorre, quando você coloca velocidade de 300, é que o tempo (step_delay) entre o "chaveamento" do pólos é muito curto para mover o eixo.

Não tenho esses valores, mas creio que testando (como você já fez) seja a melhor forma de você encontrar os valores máximos para o teu motor.

Uma coisa que você pode tentar é iniciar o motor com menor "velocidade" e ir aumentando gradativamente, até que você encontre o limite.

Só lembre-se no futuro que o arduino "para" enquanto a função
Code: [Select]
small_stepper.step(Steps2Take);  esta dando os passos. ;)
Code: [Select]

void Stepper::step(int steps_to_move)

  int steps_left = abs(steps_to_move);  // how many steps to take
 
  // determine direction based on whether steps_to_mode is + or -:
  if (steps_to_move > 0) {this->direction = 1;}
  if (steps_to_move < 0) {this->direction = 0;}
   
   
  // decrement the number of steps, moving one step each time:
  while(steps_left > 0) {


edit1: lembrei deste post: http://forum.arduino.cc/index.php?topic=165042.msg1232834#msg1232834

Deiwys

opa, valeu pelas explicações.. to com outra dúvida.. vou postar o código todo aqui..

eu gostaria de digitar um valor, e só qndo esse valor fosse digitado rodasse a função loop.. pelos print que botei.. ele fica no loop e nao para ali no serial.read.. acho que ia parar e ficar na linha até que fosse digitado o valor, se sem digitar nada ele ta passando igual e imprimindo sempre -1 na variavel digValue, sendo que eu atribuo 0 pra ela, e qndo digito algo no terminal ela imprime um valor 49.. sei la que lixo ou o que ela ta pegando pra imprimir, mas gostaria de conseguir controlar isso, com uma opcao entrar ou nao ali no if certo dai. Alguma dica?

Code: [Select]
#include <Ultrasonic.h>
#include <Stepper.h>

#define passos  100
#define echoPin 6 //Pino 6 recebe o pulso do echo
#define trigPin 5 //Pino 5 envia o pulso para gerar o echo

Ultrasonic ultrasonic(5,6);


Stepper small_stepper(passos, 8, 10, 9, 11);

int  qtdDeVoltas;

void setup()   
{
  Serial.begin(9600); //inicia a porta serial
  pinMode(echoPin, INPUT); // define o pino 6 como entrada (recebe)
  pinMode(trigPin, OUTPUT); // define o pino 5 como saida (envia)
  small_stepper.setSpeed(300); 
}

void loop()
{
  int digValue = 0;

  digValue = Serial.read();
  int x = verifica_distancia();
  Serial.println(digValue);
 
  if(digValue == 1){
    Serial.println("entrouu available");
    if(x == 1){
      qtdDeVoltas  =  1024; //1024 para uma volta completa
      small_stepper.step(qtdDeVoltas);
    } 
  }
}


int verifica_distancia(){
 
    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);

    int distancia = (ultrasonic.Ranging(CM));

    Serial.print("Distancia em CM: ");
    Serial.println(distancia);
    delay(1000);
   
    if(distancia > 10){
      return 1;
    }
    else if(distancia < 10){
      return 0;
    }
   
}

bubulindo

Tu estás a usar ASCII quando envias algo pela porta série.

Então se vires aqui http://www.asciitable.com/, vês o valor inteiro que o símbolo que envias pela porta série equivale.

Ao fazeres isto:

Code: [Select]
  int digValue = 0;
Estás a dizer que essa variável vai ser usada como um inteiro e não como um caracter (que é o que estás a fazer).

Então faz isto, troca o tipo dessa variável de int para char.

Depois aqui:

Code: [Select]
  if(digValue == 1){
    Serial.println("entrouu available");
    if(x == 1){
      qtdDeVoltas  =  1024; //1024 para uma volta completa
      small_stepper.step(qtdDeVoltas);
    } 
  }


Em vez de veres se é igual a 1 (nota que 1 é o código "SOH" e não '1'), compara com '1' assim:

Code: [Select]
  if(digValue == '1'){
    Serial.println("entrou available");
    if(x == 1){
      qtdDeVoltas  =  1024; //1024 para uma volta completa
      small_stepper.step(qtdDeVoltas);
    } 
  }


Para bloqueares o código, com a porta série tens de usar o método available.

Code: [Select]

while(Serial.available() == 0); //enquanto não receber nada na porta série... fica aqui empancado.


Por último, acho que devias estudar um pouco mais protocolos. Eu meti uns posts (muito incompletos até agora) a falar de protocolos e pelo menos esta parte do ASCII já está coberta.

Eu não sou o teu criado. Se respondo no fórum é para ajudar todos mediante a minha disponibilidade e disposição. Responder por mensagem pessoal iria contra o propósito do fórum e por isso evito-o.
Se realmente pretendes que eu te ajude por mensagem pessoal, então podemos chegar a um acordo e contrato onde me pagas pela ajuda que eu fornecer e poderás então definir os termos de confidencialidade do meu serviço. De forma contrária toda e qualquer ajuda que eu der tem de ser visível a todos os participantes do fórum (será boa ideia, veres o significado da palavra fórum).
Nota também que eu não me responsabilizo por parvoíces escritas neste espaço pelo que se vais seguir algo dito por mim, entende que o farás por tua conta e risco.

Dito isto, mensagens pessoais só se forem pessoais, ou seja, se já interagimos de alguma forma no passado ou se me pretendes convidar para uma churrascada com cerveja (paga por ti, obviamente).

Mortis

Deiwys,

Além das orientações que o bubulindo te passou, sugiro que use
Code: [Select]
if (Serial.available() > 0) {
}

que indica se tem algo para ler na serial.

Quando usas
Code: [Select]
digValue = Serial.read(); já estas a tirar um char da porta (mas se não tem char, o que pode-se tirar? ^^), por isso teu programa imprime -1 (quantidade de char na porta). E ele imprime -1 a cada loop, porque não existe condição para que ele não o faça, então veja o código "ajeitado" abaixo:
Code: [Select]

void loop()
{
  //Com esse if só faz algo se tiver "algo" na serial
  if (Serial.available() > 0) {
    char digValue = Serial.read();
    int x = verifica_distancia();
    Serial.println(digValue);
   
    if(digValue == 1){
      Serial.println("entrouu available");
      if(x == 1){
        qtdDeVoltas  =  1024; //1024 para uma volta completa
        small_stepper.step(qtdDeVoltas);
      } 
    }
  }
}

Mortis


(...)Eu meti uns posts (muito incompletos até agora) a falar de protocolos e pelo menos esta parte do ASCII já está coberta.


Mas acho que ele terá de esperar uma das partes mais importante dos teus posts, ou onde o povo parece ter mais dúvidas, And this is where the problem starts... should we send it in binary or ASCII?

bubulindo


Mas acho que ele terá de esperar uma das partes mais importante dos teus posts, ou onde o povo parece ter mais dúvidas, And this is where the problem starts... should we send it in binary or ASCII?


Ups... Tenho de voltar a isso.
O problema é que não existe uma resposta correcta para essa questão.
Eu não sou o teu criado. Se respondo no fórum é para ajudar todos mediante a minha disponibilidade e disposição. Responder por mensagem pessoal iria contra o propósito do fórum e por isso evito-o.
Se realmente pretendes que eu te ajude por mensagem pessoal, então podemos chegar a um acordo e contrato onde me pagas pela ajuda que eu fornecer e poderás então definir os termos de confidencialidade do meu serviço. De forma contrária toda e qualquer ajuda que eu der tem de ser visível a todos os participantes do fórum (será boa ideia, veres o significado da palavra fórum).
Nota também que eu não me responsabilizo por parvoíces escritas neste espaço pelo que se vais seguir algo dito por mim, entende que o farás por tua conta e risco.

Dito isto, mensagens pessoais só se forem pessoais, ou seja, se já interagimos de alguma forma no passado ou se me pretendes convidar para uma churrascada com cerveja (paga por ti, obviamente).

Mortis


Ups... Tenho de voltar a isso.
O problema é que não existe uma resposta correcta para essa questão.


Existe sim!!! "Depende" rs

O negócio é postar exemplos de cada método, então o leitor escolherá o que melhor cabe! ;)

bubulindo

Sim, depende...
Mas quem for usar binário, certamente que não precisa de ler num blog sobre como fazer. Mas não deixa de ser interessante, se calhar deixar já isso patente e de lado e focar-me em protocolos em ASCII.
Eu não sou o teu criado. Se respondo no fórum é para ajudar todos mediante a minha disponibilidade e disposição. Responder por mensagem pessoal iria contra o propósito do fórum e por isso evito-o.
Se realmente pretendes que eu te ajude por mensagem pessoal, então podemos chegar a um acordo e contrato onde me pagas pela ajuda que eu fornecer e poderás então definir os termos de confidencialidade do meu serviço. De forma contrária toda e qualquer ajuda que eu der tem de ser visível a todos os participantes do fórum (será boa ideia, veres o significado da palavra fórum).
Nota também que eu não me responsabilizo por parvoíces escritas neste espaço pelo que se vais seguir algo dito por mim, entende que o farás por tua conta e risco.

Dito isto, mensagens pessoais só se forem pessoais, ou seja, se já interagimos de alguma forma no passado ou se me pretendes convidar para uma churrascada com cerveja (paga por ti, obviamente).

Deiwys

Opa, valeu mais uma vez bubulindo e Mortis. Eu tinha realmente tentado usar esse avaliable() pra tentar 'parar' o código, mas não tinha dado certo.. mas vou tentar novamente.. e vou fazer as modificações que me orientaram..  Obrigado.

Abraço.

Mortis


(...)Mas quem for usar binário, certamente que não precisa de ler num blog sobre como fazer.(...)


Também depende lol (eu tinha dificuldades para enxergar o uso de binários, mas era-me muito simples com ascii rs)


Opa, valeu mais uma vez bubulindo e Mortis. Eu tinha realmente tentado usar esse avaliable() pra tentar 'parar' o código, mas não tinha dado certo.. mas vou tentar novamente.. e vou fazer as modificações que me orientaram..  Obrigado.

Abraço.


Estamos aqui para ajudar, diga-nos se funcionou como esperado.

bubulindo

Normalmente e tendo atenção ao computador em causa e como é enviado, usar binário é o melhor para enviar dados numéricos... não há cá conversões de strings nem nada do género. Mesmo em binário há formas de enviar o mesmo conteúdo em menos espaço com menos poder de computação.

Mas encalha-se sempre no mesmo problema... se não se estiver a fazer o software do computador, não dá mesmo para ser simples. Vou tentar deixar isso patente no próximo post.
Eu não sou o teu criado. Se respondo no fórum é para ajudar todos mediante a minha disponibilidade e disposição. Responder por mensagem pessoal iria contra o propósito do fórum e por isso evito-o.
Se realmente pretendes que eu te ajude por mensagem pessoal, então podemos chegar a um acordo e contrato onde me pagas pela ajuda que eu fornecer e poderás então definir os termos de confidencialidade do meu serviço. De forma contrária toda e qualquer ajuda que eu der tem de ser visível a todos os participantes do fórum (será boa ideia, veres o significado da palavra fórum).
Nota também que eu não me responsabilizo por parvoíces escritas neste espaço pelo que se vais seguir algo dito por mim, entende que o farás por tua conta e risco.

Dito isto, mensagens pessoais só se forem pessoais, ou seja, se já interagimos de alguma forma no passado ou se me pretendes convidar para uma churrascada com cerveja (paga por ti, obviamente).

Go Up