Show Posts
Pages: [1]
1  International / Hardware / Como puedo leer un encoder absoluto profibus? on: December 04, 2013, 09:47:01 am
Buenas,

Soy nuevo en esto así que disculpad si digo alguna burrada.
Bien, tengo un encoder absoluto profibus que me gustaría conectar con mi arduino due.
Hasta la fecha no había tenido que usar profibus para nada por lo que no se muy bien por donde empezar.
Este es el encoder:  OCD-DPC1B-1212-C100-H3P
http://www.posital.com/en/products/rotary-encoders/ixarc-product-finder/detail.php?productid=107043701
http://www.posital.com/media/en/fraba/productfinder/posital/manual-ixarc-ocd-dp.pdf

Por lo que entiendo hasta ahora creo que tendría que encender la resistencia de final de bus y usar sólo el bus que indica como entrada.
¿Cual es el voltage de salida que tiene la señal de profibus del encoder?¿Es +5v o depende de la alimentación del encoder?
Luego conectarlo a un shield rs485 y de ahí a los pines RX y TX del arduino.
Lo que tampoco entiendo es cual de los dos hilos del bus A/B va al RX y cual al TX.
Enfin, me estoy volviendo loco ya que todo es nuevo y no entiendo casi nada...

Si alguien puede decirme si voy por buen camino, alumbrar un poco el camino o si sabe de alguna otra manera para leer los datos del encoder se lo agradeceré.
2  Topics / Robotics / Re: Problem with high speed motor on: June 01, 2013, 12:21:49 pm
Hello again

I tried another sketch and have the same result. Can be a encoders problem. I see it lost ticks when it reach at this speed. It doesn't matter if I wanna read 4096 ticks per revolution or 1024. In the first case I use the code posted in the previous post, and in the second only an interrups reading the rising of the channel A. Here is the second code(the numbers in the loop are in accordance to coil position):


Code:
inline void digitalWriteDirect(int pin, boolean val){
  if(val) g_APinDescription[pin].pPort -> PIO_SODR = g_APinDescription[pin].ulPin;
  else    g_APinDescription[pin].pPort -> PIO_CODR = g_APinDescription[pin].ulPin;
}

inline int digitalReadDirect(int pin){
  return !!(g_APinDescription[pin].pPort -> PIO_PDSR & g_APinDescription[pin].ulPin);
}

const int a = 2;
const int z = 10;
volatile int tick=1;
volatile int ticklect=1;

void setup() {
    pinMode(33, OUTPUT);
    pinMode(31, OUTPUT);
    pinMode(35, OUTPUT);
    digitalWrite(31, LOW);
    digitalWrite(35, LOW);
    digitalWrite(33, LOW);
    pinMode(a, INPUT);
    pinMode(z, INPUT);
    digitalWrite(a, LOW);
    digitalWrite(z, LOW);   
    attachInterrupt(z, zrising, RISING);
    attachInterrupt(a, acount, RISING);
   
}   


void loop() {
 
  for (tick==5; tick<23; tick=ticklect){
   digitalWriteDirect(33, LOW);
   digitalWriteDirect(31, LOW);
   digitalWriteDirect(35, HIGH);
  }
 
  for (tick==33; tick<52; tick=ticklect){
   digitalWriteDirect(35, LOW);
   digitalWriteDirect(31, LOW);
   digitalWriteDirect(33, HIGH);
  }
 
  for (tick==61; tick<81; tick=ticklect){
    digitalWriteDirect(35, LOW);
    digitalWriteDirect(33, LOW);
    digitalWriteDirect(31, HIGH);
  }
 
  for (tick==91; tick<109; tick=ticklect){
   digitalWriteDirect(33, LOW);
   digitalWriteDirect(31, LOW);
   digitalWriteDirect(35, HIGH);
  }
 
  for (tick==119; tick<138; tick=ticklect){
   digitalWriteDirect(35, LOW);
   digitalWriteDirect(31, LOW);
   digitalWriteDirect(33, HIGH);
  }
 
  for (tick==147; tick<164; tick=ticklect){
    digitalWriteDirect(35, LOW);
    digitalWriteDirect(33, LOW);
    digitalWriteDirect(31, HIGH);
  }
 
  for (tick==175; tick<195; tick=ticklect){
   digitalWriteDirect(33, LOW);
   digitalWriteDirect(31, LOW);
   digitalWriteDirect(35, HIGH);
  }
 
  for (tick==204; tick<223; tick=ticklect){
   digitalWriteDirect(35, LOW);
   digitalWriteDirect(31, LOW);
   digitalWriteDirect(33, HIGH);
  }
 
  for (tick==232; tick<252; tick=ticklect){
    digitalWriteDirect(35, LOW);
    digitalWriteDirect(33, LOW);
    digitalWriteDirect(31, HIGH);
  }
 
  if (ticklect==256){
    ticklect=1;
    tick=1;
  }
 
}
 
 
 
 



void zrising() {
    ticklect=1;
     
}

 
void acount(){

  ticklect++;

}


The both codes gives the same speed.
I think the calculation is correct because it start so fast but when arrive at 100-120RPM don't speed up more, and the counter starts to lose tics.
A encoder can seem ok when driving it by hand, but count wrong when it speeds up?
I'm little suprised because it seems that the due can handle this code more than easy. Some suggestion?
3  Topics / Robotics / Problem with high speed motor on: May 29, 2013, 03:48:56 am
Hello

I'm trying to make a motor with 12 magnets in the rotor and 3 driving coils, using an incremental encoder and a arduino due.
Until now I have tried several sketchs with no results. I tried interrupts at both channels, hardware quadrature...
The best counting metod so far is the hardware quadrature, but it lose ticks when it reach at 100, 120rpm. With hardware quadrature the resolution of the encoder is 4096ticks per revolution.

This is the hardware quadrature code:

Code:
const int quad_A = 2;
const int quad_B = 13;
const unsigned int mask_quad_A = digitalPinToBitMask(quad_A);
const unsigned int mask_quad_B = digitalPinToBitMask(quad_B); 

void setup() {
    Serial.begin(115200); 
    delay(100);
   
    // activate peripheral functions for quad pins
    REG_PIOB_PDR = mask_quad_A;     // activate peripheral function (disables all PIO functionality)
    REG_PIOB_ABSR |= mask_quad_A;   // choose peripheral option B   
    REG_PIOB_PDR = mask_quad_B;     // activate peripheral function (disables all PIO functionality)
    REG_PIOB_ABSR |= mask_quad_B;   // choose peripheral option B
   
    // activate clock for TC0
    REG_PMC_PCER0 = (1<<27);
    // select XC0 as clock source and set capture mode
    REG_TC0_CMR0 = 5;
    // activate quadrature encoder and position measure mode, no filters
    REG_TC0_BMR = (1<<9)|(1<<8)|(1<<12);
    // enable the clock (CLKEN=1) and reset the counter (SWTRG=1)
    // SWTRG = 1 necessary to start the clock!!
    REG_TC0_CCR0 = 5;

I use a counter to detect changes in REG_TC0_CV0, and a shooter to open and close the 3 Mosfet circuits. Don't have the last code here, I will post it as soon as possible, but it is something like this:

Code:
void Loop(){

tick=REG_TC0_CV0;

   if (tick>counter){
      shooter++;
   }

   if (shooter>0 && shooter<113){   //all the positions like this
      digitalWriteDirect(31, HIGH);
   }
   else
   if (shooter>...

   else
       digitalWriteDirect(31, LOW);   // all the transistors off before change coil
       digitalWriteDirect(33, LOW);
       digitalWriteDirect(35, LOW);
   


The digitalWriteDirect code is the next one:

inline void digitalWriteDirect(int pin, boolean val){
  if(val) g_APinDescription[pin].pPort -> PIO_SODR = g_APinDescription[pin].ulPin;
  else    g_APinDescription[pin].pPort -> PIO_CODR = g_APinDescription[pin].ulPin;
}

inline int digitalReadDirect(int pin){
  return !!(g_APinDescription[pin].pPort -> PIO_PDSR & g_APinDescription[pin].ulPin);
}

Some suggestion? I'm new in this programing stuff and don't understand it very well. There is a metod to make what I'm doing much more eficiently?

Thanks!
4  International / Español / Problema de velocidad o sincronización con motor a alta velocidad on: April 27, 2013, 09:50:30 am
Saludos

Este es mi primer tópico así que saludos a todos. Tenemos un proyecto de un motor con tres bobinas que hace girar un rotor con 12 imanes. A baja velocidad todo va bien pero cuando alcanza unas 100 RPM empieza a frenarse. No se porque no alcanza más velocidad. O el código no traduce los ticks de manera correcta (no creo porque a baja velocidad va bien), o el arduino no puede alcanzar a leer y disparar las bobinas lo suficientemente rápido. No se, porque son 2048 ticks del encoder y 36 pulsaciones de las bobinas por revolución, por lo que no debería de tener problemas. Lo que pienso es que el código no está bien depurado ya que soy muy novato con esto de la programación. Os dejo el código por si alguien pudiese ayudarme:

/* read a rotary encoder with interrupts
   Encoder hooked up with common to GROUND,
   encoder0PinA to pin 2, encoder0PinB to pin 4 (or pin 3 see below)
   it doesn't matter which encoder pin you use for A or B 

   uses Arduino pullups on A & B channel outputs
   turning on the pullups saves having to hook up resistors
   to the A & B channel outputs

*/
#include <digitalWriteFast.h>;


#define encoder0PinA  2        // Definimos pines de entrada (Canal A y B del encoder y el potenciometro)
#define encoder0PinB  4       
#define potpin 2
#define bobina1 13             // Definimos pines de salida (tres bobinas)
#define bobina2 12
#define bobina3 8


volatile unsigned long _Grados = 20;       // Variable _Grados que traduce los ticks del encoder a 360
volatile unsigned long encodertick = 0;    // Variable para contar los ticks del encoder
volatile unsigned long contador = 0;       // Contador para detectar los cambios en grados
unsigned int dur;                          // Duración del pulso en grados
unsigned int durAnt;                     
volatile unsigned long disparador = 20;    // Disparador de las bobinas

void setup() {


  Serial.begin(9600);
  pinMode(encoder0PinA, INPUT);
  digitalWrite(encoder0PinA, HIGH);       // turn on pullup resistor
  pinMode(encoder0PinB, INPUT);
  digitalWrite(encoder0PinB, HIGH);       // turn on pullup resistor
  pinMode(bobina1, OUTPUT);
  pinMode(bobina2, OUTPUT);
  pinMode(bobina3, OUTPUT);

  attachInterrupt(0, doEncoder, CHANGE);  // encoder pin on interrupt 0 - pin 2
  Serial.println ("Hasi");
}

void loop(){
 
   if (disparador > 29){                                             // Limita el disparador a 30 grados
  disparador=0;
  }
  if (_Grados>contador){                                             // Si se mueve un grado aumenta disparador
    disparador++;
    contador=_Grados;
  }
 
  if ((disparador < 0+dur) && (disparador > 0)){                      // Si esta entre los grados 0-10 disparar bobina2
   digitalWriteFast(bobina2, HIGH);
  }
  else
  if ((disparador < 10+dur) && (disparador > 10)){                    // Si esta entre los grados 10-20 disparar bobina3
   digitalWriteFast(bobina3, HIGH);
  }
   
    else
   
    if ((disparador < 20+dur) && (disparador > 20)){                   // Si esta entre los grados 20-30 disparar bobina1
   digitalWriteFast(bobina1, HIGH);
  }
  else{
    digitalWriteFast(bobina1, LOW);
    digitalWriteFast(bobina2, LOW);
    digitalWriteFast(bobina3, LOW);
  }
   
 
  if (encodertick > 2046){                                               // Resetea el contador de ticks cada revolucion
        encodertick = 0;
        contador=0;
        disparador=0;
        _Grados = 0;
       
  }
 
}

void doEncoder() {
  /* If pinA and pinB are both high or both low, it is spinning
   * forward. If they're different, it's going backward.
   *
   * For more information on speeding up this process, see
   * [Reference/PortManipulation], specifically the PIND register.
   */
  _Grados=encodertick;
  _Grados=map(_Grados, 0, 2047, 0, 359);
 
  if (digitalReadFast(encoder0PinA) == digitalReadFast(encoder0PinB)) {
    encodertick++;
  } else {
    encodertick--;
  }
 
}       

Espero que alguien pueda ayudarme. Muchas gracias!
Pages: [1]