Go Down

Topic: libreria ROTARY.h y mega 2560 (Read 1 time) previous topic - next topic

apaserv

Hola a todos, sigo dandole y dándole a mis proyectos, y por tanto surgen problemas.
Hoy traigo el siguiente problema, que no se exactamente si es hardware o software.

Un sketch en Arduino Uno rev3 , funciona perfectamente el encoder con esta librería.
Utiliza los pines 2 y 3 (interrupciones).
La función del encoder es cambiar la frecuencia del TX/RX.

Paso lo mismo al mega 2560 y no funciona el encoder ni en 2 y 3 ni en 18 y 19.




Code: [Select]

#include <Keypad.h>
#include <LiquidCrystal_I2C.h>
#include <avr/pgmspace.h>
#include <math.h>
#include <Rotary.h>
#include <EEPROM.h>
#include <Wire.h>

Rotary r = Rotary(2,3); //  pines encoder(interrpt)

void setup(){

PCICR |= (1 << PCIE2);
  PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
  sei(); /////-------------------------------SEI?

}


void loop() {}




// Interrupt routine to catch the rotary encoder
ISR(PCINT2_vect) {
  scan=0;
  unsigned char result = r.process();
  if (result) {   
    if (result == DIR_CW){rx=rx+increment;}
    else {rx=rx-increment;};       
      if (rx >=30000000){rx=rx2;}; // Límíte superior VFO
     
      if (rx <=100000){rx=rx2;}; //              inferior VFO
  }
}








es parte de código del encoder, ya que el programa tiene muchas subrutinas y es extenso

Realmente no se que pasa porque debería funcionar , alguna idea sobre el tema??
Gracias
Daniel

surbyte


Quote
Paso lo mismo al mega 2560 y no funciona el encoder ni en 2 y 3 ni en 18 y 19.
Y no se te ocurrió pensar que el MEGA 2560 es un poco bastante diferente que el UNO?
Y si vas y miras como son las interrupcciones descubrirás que son diferentes. Tienen diferentes números.

Google: Arduino interrupts

lightcalamar

Yo he tenido un  problema parecido por no decir "casi" idéntico al que presentas.
Realice en su día como no de mi proyecto de mi Radio FM con RDS y al exportar a Arduino MEGA, cataclak!!! no funcionaba.

Tuve que recurrir paa usar mi encoder, el cual se usa solo para sintonía `fina`con pasos de 100KHertz y va de lurjo al día de hoy.
Lo busqué y me costo mucho y al final casí  desistí porque no funcionaba y creo que la librería no esta preparada para Arduino MEGA así de claro.
Al final me decanté por buscar el la red ISR ENCODER seguro que encuentras la forma. De no ser, yo te escribo el código.

Saludos!
Mi proyecto Radio FM con RDS -  MDC v1.0;
https://forum.arduino.cc/index.php?topic=400484.0
https://forum.arduino.cc/index.php?topic=448606.0
https://github.com/lightcalamar

surbyte

#3
Jun 11, 2016, 09:04 pm Last Edit: Jun 11, 2016, 09:07 pm by surbyte
Algun día haremos todos como yo estoy viendo que los buenos programadores hacen.
Ponen en cada librería el comentario del sitio de donde fue descargada ejemplo y si no lo hacen es porque esta provista por el IDE.


Code: [Select]
#include <Keypad.h>
#include <LiquidCrystal_I2C.h>     //
#include <avr/pgmspace.h>
#include <math.h>
#include <Rotary.h>     // https://github.com/brianlow/Rotary
#include <EEPROM.h>
#include <Wire.h>



Ahora tu concentración debe fijarte acá
Code: [Select]

  PCICR |= (1 << PCIE2);
  PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);


Son estos registros los mismos en UNO que en MEGA? No.
Ahora de memoria no se la respuesta. Pero busca por aca.

apaserv

Hola, probé lo siguiente y en principio funciono, mal pero funciono.
Lo que hacia era que por los rebotes sumaba y restaba los valores a lo loco.
Code: [Select]


#include <Keypad.h>
#include <LiquidCrystal_I2C.h>
#include <avr/pgmspace.h>
#include <math.h>


#include <EEPROM.h>
#include <Wire.h>


void setup()
{
 // INTERRUPCIONES
  attachInterrupt(0, funsuma,FALLING);
  attachInterrupt(1, funresta,FALLING);
  sei();
}



 void funsuma()
{
  rx=rx+increment;
  showFreq();
  
 }

  void funresta()
{
  rx=rx-increment;
  showFreq();
    
 }





showFreq muestra la nueva frecuencia de trabajo

pero ahora no funciona mas!!!!!!!!!

Leí todo lo que encontré sobre interrupciones del mega.

lightcalamar podías pasarme el código que te funcionó a ver si consigo encontrar la relación entre Uno y mega??
Gracias
Daniel


surbyte

#5
Jun 13, 2016, 10:37 pm Last Edit: Jun 13, 2016, 10:40 pm by surbyte
Lee esto, investiga un poco
http://forum.arduino.cc/index.php?topic=45239.40

Code: [Select]
#include <avr/interrupt.h>
#include <avr/io.h>


void setup() {
 pinMode(10, INPUT); // UP pin of trackball
 pinMode(11, INPUT); // DOWN pin of trackball
 pinMode(12, INPUT); //LEFT pin of trackball
 pinMode(13, INPUT); // RIGHT pin of trackball
 pinMode(15, INPUT); // BUTTON pin of trackball
 Serial.begin(115200);
 PCICR |= (1 << PCIE0); // enable PCINT0
 PCICR |= (1 << PCIE1); // enable PCINT1
 PCMSK0 |= (1 << PCINT4); // mask for bit4 of port B (pin 10)
 PCMSK0 |= (1 << PCINT5); // mask for bit5 of port B (pin 11)
 PCMSK0 |= (1 << PCINT6); // mask for bit6 of port B (pin 12)
 PCMSK0 |= (1 << PCINT7); // mask for bit7 of port B (pin 13)
 PCMSK1 |= (1 << PCINT9); // mask for bit0 of port J (pin 15)
}

volatile boolean print_flag0 = false;      // PCINT0 flag
volatile boolean print_flag1 = false;      // PCINT1 flag
volatile byte pcint0_pins = B00000000;     // variable for current port B bits
volatile byte pcint0_pinsLast = B00000000; // variable for previous port B bits
volatile byte pcint1_pins = B00000000;     // variable for current port J bits
volatile byte pcint1_pinsLast = B00000000; // variable for previous port J bits

ISR(PCINT0_vect) // PCINT0 ISR
{
 byte saveSREG = SREG; // Save SREG
 noInterrupts();                                                      // disable interrupts
 pcint0_pins ^= ((PINB & B11110000) ^ (pcint0_pinsLast & B11110000)); // store bits that have changed
 pcint0_pinsLast = pcint0_pins;                                       // store current bits to previous bits
 print_flag0 = true;                                                  // set flag to indicate PCINT0 interrupt
 SREG = saveSREG;                                                     // restore SREG
}

ISR(PCINT1_vect) // same as above for PCINT1
{
 byte saveSREG = SREG;
 noInterrupts();
 pcint1_pins ^= ((PINJ & B00000001) ^ (pcint1_pinsLast & B00000001));
 pcint1_pinsLast = pcint1_pins;
 print_flag1 = true;
 SREG = saveSREG;
}


void loop() {
 if (print_flag0 == true) {   // for PCINT0
   noInterrupts();            // disable interrupts
   byte pci0 = pcint0_pins;   // transfer value
   interrupts();              // enable interrpts
   Serial.print("PCINT0 = "); // prints bit values of port B
   Serial.println(pci0, BIN);
   print_flag0 = false;       // reset flag
 }
 if (print_flag1 == true) { // same as above for pot J
   noInterrupts();
   byte pci1 = pcint1_pins;
   interrupts();
   Serial.print("PCINT1 = ");
   Serial.println(pci1, BIN);
   print_flag1 = false;
 }
}


Aqui esta la table de Interrupciones por Pin en el MEGA
Also, here is a table of the available Pin Change interrupts for the Mega.

PC Interrupt#       PCI Control Reg.      PCI Mask      Port/Bit      Arduino Mega Pin
----------------------------------------------------------------------------------------------------------------------
PCINT0:            PCICR = PCIE0 = Bit0,      PCMSK0 = Bit0,      PortB Bit0,      Pin = 53
PCINT1:            PCICR = PCIE0 = Bit0,      PCMSK0 = Bit1,      PortB Bit1,      Pin = 52
PCINT2:            PCICR = PCIE0 = Bit0,      PCMSK0 = Bit2,      PortB Bit2,      Pin = 51
PCINT3:            PCICR = PCIE0 = Bit0,      PCMSK0 = Bit3,      PortB Bit3,      Pin = 50
PCINT4:            PCICR = PCIE0 = Bit0,      PCMSK0 = Bit4,      PortB Bit4,      Pin = 10
PCINT5:            PCICR = PCIE0 = Bit0,      PCMSK0 = Bit5,      PortB Bit5,      Pin = 11
PCINT6:            PCICR = PCIE0 = Bit0,      PCMSK0 = Bit6,      PortB Bit6,      Pin = 12
PCINT7:            PCICR = PCIE0 = Bit0,      PCMSK0 = Bit7,      PortB Bit7,      Pin = 13

PCINT8:            PCICR = PCIE1 = Bit1,      PCMSK1 = Bit0,      PortE Bit0,      Pin = 0 (USART0) !!!Avoid using!!!
PCINT9:            PCICR = PCIE1 = Bit1,      PCMSK1 = Bit1,      PortJ Bit0,      Pin = 15
PCINT10:          PCICR = PCIE1 = Bit1,      PCMSK1 = Bit2,      PortJ Bit1,      Pin = 14
** PCINT11:      PCICR = PCIE1 = Bit1,      PCMSK1 = Bit3,      PortJ Bit2,      NOT_AVAILABLE
** PCINT12:      PCICR = PCIE1 = Bit1,      PCMSK1 = Bit4,      PortJ Bit3,      NOT_AVAILABLE
** PCINT13:      PCICR = PCIE1 = Bit1,      PCMSK1 = Bit5,      PortJ Bit4,      NOT_AVAILABLE
** PCINT14:      PCICR = PCIE1 = Bit1,      PCMSK1 = Bit6,      PortJ Bit5,      NOT_AVAILABLE
** PCINT15:      PCICR = PCIE1 = Bit1,      PCMSK1 = Bit7,      PortJ Bit6,      NOT_AVAILABLE

PCINT16:      PCICR = PCIE2 = Bit2,      PCMSK2 = Bit0,      PortK Bit0,      Pin = 62(A8)
PCINT17:      PCICR = PCIE2 = Bit2,      PCMSK2 = Bit1,      PortK Bit1,      Pin = 63(A9)
PCINT18:      PCICR = PCIE2 = Bit2,      PCMSK2 = Bit2,      PortK Bit2,      Pin = 64(A10)
PCINT19:      PCICR = PCIE2 = Bit2,      PCMSK2 = Bit3,      PortK Bit3,      Pin = 65(A11)
PCINT20:      PCICR = PCIE2 = Bit2,      PCMSK2 = Bit4,      PortK Bit4,      Pin = 66(A12)
PCINT21:      PCICR = PCIE2 = Bit2,      PCMSK2 = Bit5,      PortK Bit5,      Pin = 67(A13)
PCINT22:      PCICR = PCIE2 = Bit2,      PCMSK2 = Bit6,      PortK Bit6,      Pin = 68(A14)
PCINT23:      PCICR = PCIE2 = Bit2,      PCMSK2 = Bit7,      PortK Bit7,      Pin = 69(A15)

apaserv

Hola, siguiendo vuestros consejos, leí, leí, pensé!!!(surbyte maestro!!!)
conseguí que el Mega reaccione a las interrupciones de encoder, pero todavía no consigo que la sub rutina

ISR(PCINT0_vect) me devuelva algo.

Utlizé las interrupciones de los pines 12 y 13
PCINT6:            PCICR = PCIE0 = Bit0,      PCMSK0 = Bit6,      PortB Bit6,      Pin = 12
PCINT7:            PCICR = PCIE0 = Bit0,      PCMSK0 = Bit7,      PortB Bit7,      Pin = 13

Veo que al girar el encoder parpadea un led en el mega, pero no entra a la subrutina.
Si hago ISR(PCINT1_vect) veo que el lcd (en pines 20 y 21 porque esta con interfase i2c) se apaga cada vez que muevo el encoder

Sigo analizando todo esto.
Saludos
Daniel

apaserv

Hola , buenas  noticias.
Ya funciona con el Mega!!!!!!!!
Code: [Select]




#include <rotary.h> //http://www.buxtronix.net/



Rotary r = Rotary(12,13);

void setup() {
Serial.begin(115200);
PCICR |=  (1 << PCIE0);

PCMSK0 |= (1 << PCINT6) | (1 << PCINT7) ;
sei();
}

void loop() {

}

ISR(PCINT0_vect) {
char result = r.process();

if (result) {
Serial.println(result == DIR_CW ? "SUMA" : "RESTA");
}

}



Rotary r = Rotary(12,13);

void setup() {
Serial.begin(115200);
PCICR |=  (1 << PCIE0);

PCMSK0 |= (1 << PCINT6) | (1 << PCINT7) ;
sei();
}

void loop() {

}

ISR(PCINT0_vect) {
char result = r.process();

if (result) {
Serial.println(result == DIR_CW ? "SUMA" : "RESTA");
}

}







Esta librería permite 2 encoder.(ver el ejemplo)
Si no la pueden bajar, me avisan, hay que sacar la otra Rotary si es que la tienen incluida.
apaserv@hotmail.com

Espero que le sirva a alguien mas que a mi!!!!!!!!!
Gracias por hacerme pensar, ahora ya entendi el tema
Un abrazo a todos.
Daniel.

PD: Maestro, podés cerrar el tema(  ya volveré !!!!!!!! jaja)

surbyte

De tanto en tanto encontramos una persona como apaserv que se esfuerza con los consejos que le damos.
En lo personal me motiva para seguir ayudando. 
1 caso positivo por 99 que no leen las normas, no postean como deben, o solo piden que se lo hagan y si les dices algo se molestan. Ojalá muchos lean esto para que puedan recapacitar.

Que gusto me da!! 

Este tema es mas importante de lo que parece.
Porque utiliza pines comunes como llamados a interrupciones y por ejemplo para situaciones como un teclado, permite usar esos pines como una lectura instantánea si el programa lo requiere.

Go Up