Go Down

Topic: Encoder switch, port manipulation and the Arduino Mega (Read 962 times) previous topic - next topic

Petertje

Maybe a little bit off-topic but I am stuck with this......


I build a .wav player with MenWiz and an encoder en some other libraries. I can make the seperate modules work on an Uno. But to use all the modules as an application I need to use a Mega because of the memory restrictions on an Uno (or any other 328).

The main source is from quick_tour_rotEnc.ino  which can be found at: http://forum.arduino.cc/index.php?topic=99693.255;wap2

I need to know how to translate the following section of code to code that can be used on a Mega.
It has to do with port manipulation and it is very hard to find documentation about this subject.
Code: [Select]

 PORTC |= _BV(PORTC0) | _BV(PORTC1) | _BV(PORTC2) | _BV(PORTC3);   // enable pullup for pins
 PCMSK1 = _BV(PCINT8) | _BV(PCINT9) | _BV(PCINT10) | _BV(PCINT11); // enable button pin change interrupt A0 A1 A2 A3
 PCICR = _BV(PCIE1);                                               // C-port interrupt enable

It works on an Uno or Nano, no problems at all. But it will not work on the Mega.

I tried using this table from http://lars.mec.ua.pt/public/LAR%20Projects/Perception/2012_AndreOliveira-@Artur/hardware/arduino%20stuff/encoder/uno_counter_shield/uno_Counter.h
Code: [Select]
// Arduino Mega Digital Pin 35 [ATMEL ATMEGA PORTC 2] -> HCTL 2032 Pin  2 EN1
// Arduino Mega Digital Pin 36 [ATMEL ATMEGA PORTC 1] -> HCTL 2032 Pin  7 OE   - Active LOW
// Arduino Mega Digital Pin 37 [ATMEL ATMEGA PORTC 0] -> HCTL 2032 Pin 32 X/Y

But it also does not work.

I am stuck, can anybody help me?

The complete code (with me messing about....)


Code: [Select]
/* Sketch for Arduino/IDE 1.x (quick_tour_rotEnc.ino). Based on MENWIZ quick_tour.ino
Detent rotary encoder with two buttons and 16x2 LCD example.
Input signal using interrupts on pin A0/1 for encoder and A2/3 for buttons.
Based on BenF forum sketch 25may2011 and debounce from delphino-999 forum sketch 19oct2012.
HW: Roboduino (http://arduino-direct.com/sunshop) and rotary encoder with pushbutton (Panasonic 30 PPR, audiosector, www.ebay.com)
Desember 2012, Hans Fredrik Sandberg
Pin allocation on Uno
D4      LCD DB4
D5      LCD DB5
D6      LCD DB6
D7      LCD DB7
D8      LCD RS  
D9      LCD Enable
D10     LCD backlit control
A0 D14  Rotary A left 1ยงยง
A1 D15  Rotary B right 2
A2 D16  Button 1 confirm 6
A3 D17  Button 2 escape 5
*/
#include <Wire.h>

#include <EEPROM.h>
#include <LiquidCrystal_I2C.h>

#include <ClickEncoder.h>


#include <MENWIZ.h>

/* SD card sound */
#include <SD.h>                      // need to include the SD library
#define SD_ChipSelectPin 53  //example uses hardware SS pin 53 on Mega2560
//#define SD_ChipSelectPin 10  //using digital pin 4 on arduino nano 328, can use other pins
#include <TMRpcm.h>           //  also need to include this library...
#include <SPI.h>


byte customChar[8] = {
 B10001,
 B01110,
 B00000,
 B01110,
 B10001,
 B01110,
 B10101,
 B10101
};



volatile byte virtualButton = 0;     // which button was pressed
volatile int push[2] = {
 0,0};        // Variable to pass button press back to main loop
long debouncing_time = 40;           // Debouncing Time in Milliseconds
volatile unsigned long last_micros;  // Variable to keep time while debounce

menwiz menu;

TMRpcm tmrpcm;   // create an object for use in this sketch




LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);


extern byte MW_navbtn;        // needed to run the software key navigation in Menwiz
int  list,setp=110;

void setup()
{
 Serial.begin(9600);
 Serial.println("Start");


 tmrpcm.speakerPin = 9; //5,6,11 or 46 on Mega, 9 on Uno, Nano, etc

 if (!SD.begin(SD_ChipSelectPin)) {  // see if the card is present and can be initialized:
   Serial.println("SD fail");  
   return;   // don't do anything more if not
 }
 //   lcd.createChar(0, customChar);

 PORTC |= _BV(PORTC0) | _BV(PORTC1) | _BV(PORTC2) | _BV(PORTC3);   // enable pullup for pins
 PCMSK1 = _BV(PCINT8) | _BV(PCINT9) | _BV(PCINT10) | _BV(PCINT11); // enable button pin change interrupt A0 A1 A2 A3
 PCICR = _BV(PCIE1);                                               // C-port interrupt enable

 _menu *r,*s1,*s2;
 menu.begin(&lcd,20,4);
 MW_navbtn=4;  // force 4 or 6 buttons mode for menu navigation -> MW_navbtn=4; or MW_navbtn=6;
 menu.addUsrNav(navMenu,MW_navbtn);


 r=menu.addMenu(MW_ROOT,NULL,F("Mesdag hoofdmenu"));
 s1=menu.addMenu(MW_SUBMENU,r, F("Talen"));
 s2=menu.addMenu(MW_VAR,s1, F("Talen II"));
 s2->addVar(MW_LIST,&list);
 s2->addItem(MW_LIST, F("Pools"));
 s2->addItem(MW_LIST, F("Nederlands"));
 s2->addItem(MW_LIST, F("Engels (Amerikaans)"));
 s2->addItem(MW_LIST, F("Pools2"));
 s2->addItem(MW_LIST, F("Pools3"));
 s2->addItem(MW_LIST, F("Pools4"));
 s2->addItem(MW_LIST, F("Pools5"));

 //s2=menu.addMenu(MW_VAR,s1, F("Node4-int"));
 //s2->addVar(MW_AUTO_INT,&setp,0,120,1);
 //s2=menu.addMenu(MW_VAR,s1,F("back"));
 //s2->addVar(MW_ACTION,escapeFunct);
 //s2->setBehaviour(MW_ACTION_CONFIRM,false);  // MW_ACTION_IMMEDIATE described in MENWIZ_0-6-0_QUICK TOUR.pdf  
 // s1=menu.addMenu(MW_VAR,r, F("Node2-action"));
 //s1->addVar(MW_ACTION,myfunc);

 tmrpcm.play("music.wav"); //the sound file "music" will play each time the arduino powers up, or is reset

 sprintf(menu.sbuf,"Mesdag taal\nselectie applicatie\n\nKloonDuino.nl",1);  // Splash screen shown at startup time
 menu.addSplash((char *) menu.sbuf,4000);           // Shown for msecs
 menu.addUsrScreen(msc,30000);                       // Default screen function shown after msecs since last button push
 digitalWrite(10, HIGH);                            // LCD backlit on
}

void loop()    
{
 menu.draw();                    // NAVIGATION MANAGEMENT & DRAWING ON LCD. NOT BLOCKING has to be the first in the void loop
 /*
 put your regular code here
  */
 if ( push [0] > 0 ) { // confirm
   virtualButton = 6;
   push[0] = 0;
 }
 if ( push [1] > 0 ) { // escape
   virtualButton = 5;
   push[1] = 0;
 }
}

ISR(PCINT1_vect) // handle pin change interrupt for A0 to A5  here
{
 Serial.println("Ja\n");
 static uint8_t AB = 0x03;     //lookup table index
 static long encval = 0;           //encoder value
 static const int8_t enc_states[] =   {
   0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0        };
 static uint8_t btn = _BV(PINC2) | _BV(PINC3);
 uint8_t t = PINC;  // read port status

 // check for rotary2 state change on pin A0 A1
 AB <<= 2;                  // save previous state
 AB |= ( t & 0x03 );       // add current state, from lower port pin pair
 encval += enc_states[AB & 0x0f];
 if( encval > 1 ) {         // step forward
   virtualButton = 2;
   encval = 0;
 }
 else if( encval < -1 ) {   // step backwards
   virtualButton = 1;
   encval = 0;
 }

 // check if buttons are pushed
 t &= _BV(PINC2) | _BV(PINC3); // A2 A3
 if (t != btn) {  // activity on pins, we're only interested in high to low transitions
   if((long)(micros() - last_micros) >= debouncing_time * 1000) {  
     push[0] |= !(t & _BV(PINC2));
     push[1] |= !(t & _BV(PINC3));
     btn = t;
     last_micros = micros();  // start/restart bounce guard timer (covers make and break)
   }
 }
}

void myfunc(){
 Serial.println("ACTION FIRED");
 Serial.println("Taal gekozen is:");

}

int navMenu() // called from menu.draw
{
 switch (virtualButton)
 {
 case 5: // Escape
   virtualButton = 0;
   return MW_BTE;
   break;
 case 6: // Confirm
   virtualButton = 0;
   return MW_BTC;
   break;
 case 1: // Up
   virtualButton = 0;
   return MW_BTU;
   break;
 case 2: // Down
   virtualButton = 0;
   return MW_BTD;
   break;
 case 0: // no button
   return MW_BTNULL;
   break;
 }
}

void escapeFunct() {
 Serial.println("Back Called");
 virtualButton = 5;  //simulate escape button press, for use in some menus
}

// user defined default screen.
void msc()
{
 sprintf(menu.sbuf,"Proc.time:%ld\nFr.mem:%d\n",millis()/1000,(int)menu.freeRam());
 menu.drawUsrScreen(menu.sbuf);
}




Go Up