Ajuda com converção de atmega328 para mega2560

Olá a todos
Estou com um problema que não sei como resolver. Eu tenho um código que foi feito para atemega328, mas a minha board é uma mega 2560, queria adaptar o código a esta board, mas estou a encontrar bastantes dificuldades com os botões que estão definidos no código.
O código tem os botões definidos para ligar da seguinte forma
/ _____ Pino A3 / _____ Pino A4 / _____ Pino A5
GND ____|
|________________|

O código é este https://code.google.com/p/opengauge/source/browse/trunk/mpguino/mpguino.cpp?r=201
Eu sei que o codigo é enorme mas procurem olhar só para a parte dos botões.
Desde já agradeço toda a vossa ajuda.

Obrigada
José Rodrigues

E se tu procurasses a parte dos botões, copiasses e metesses aqui no fórum? Ou, e se tu visses quais são os pinos e ligasses lá os botões? Os pinos A3,4 e 5 estão definidos no Mega bem como nos outros.

bubulindo:
E se tu procurasses a parte dos botões, copiasses e metesses aqui no fórum? Ou, e se tu visses quais são os pinos e ligasses lá os botões? Os pinos A3,4 e 5 estão definidos no Mega bem como nos outros.

Eu posso copiar o código dos botões, o meu receio é ficar algo por copiar que interfira nos mesmos.
Já liguei lá os pinos mas não funciona, o PCINT11, PCINT12 e PCINT13 aparentemente no Mega não existem, tentei mudar para outros nas também não me funciona.
Parte do código está em baixo e tem algumas alterações que fiz e que estão identificadas.
Espero não vos estar a induzir em erro com este código.

/* 
 Buttons
 left C3 (pcint11)
 middle  C4 (pcint12)
 right C5 (pcint13)
 */

#define outhi(port,pin) PORT##port |= ( 1 << P##port##pin )
#define outlo(port,pin) PORT##port &= ~( 1 << P##port##pin )

#define lbuttonBit ( 1 << 3 )
#define mbuttonBit ( 1 << 4 )
#define rbuttonBit ( 1 << 5 )

void enableLButton() {
  	//PCMSK1 |= (1 << PCINT11);
	PCMSK2 |= (1 << PCINT19);  // Alteração
}
void enableMButton() {
  	//PCMSK1 |= (1 << PCINT12);
	PCMSK2 |= (1 << PCINT20);  // Alteração
}
void enableRButton() {
        //PCMSK1 |= (1 << PCINT13);
	PCMSK2 |= (1 << PCINT21);  // Alteração
}

#define enableLButtonID 1
#define enableMButtonID 2
#define enableRButtonID 3


        //PORTC |= (1 << 5) | (1 << 4) | (1 << 3); //button pullup resistors
	PORTK |= (1 << PK5) | (1 << PK4) | (1 << PK3); // Alteração


	//PCMSK1 |= (1 << PCINT8);
	PCMSK2 |= (1 << PCINT16);  // Alteração
	enableLButton();
	enableMButton();
	enableRButton();
	//PCICR |= (1 << PCIE1);
	PCICR |= (1 << PCIE2); // Alteração

Obrigada por tudo.
José Rodrigues

Assumindo que estás a ligar os botões no sítio correcto…

Isto é estranho…

   //PORTC |= (1 << 5) | (1 << 4) | (1 << 3); //button pullup resistors
	PORTK |= (1 << PK5) | (1 << PK4) | (1 << PK3); // Alteração

Sabes o que é PK5,4,3 ?

Edit:

Eu acho esquisito esse PK3,4,5… e pode ser o que te dá problemas.

Experimenta isto:

void setup() {

Serial.begin(19200);
delay(1000);

Serial.print ("PK3 = ");
Serial.println(PK3);

if (PK3 == 3) Serial.println("nao e isto");

}
void loop(){}

Que aparece?

bubulindo:
Assumindo que estás a ligar os botões no sítio correcto…

Isto é estranho…

   //PORTC |= (1 << 5) | (1 << 4) | (1 << 3); //button pullup resistors
PORTK |= (1 << PK5) | (1 << PK4) | (1 << PK3); // Alteração



Sabes o que é PK5,4,3 ? 

Edit: 

Eu acho esquisito esse PK3,4,5... e pode ser o que te dá problemas. 

Experimenta isto: 



void setup() {

Serial.begin(19200);
delay(1000);

Serial.print ("PK3 = ");
Serial.println(PK3);

if (PK3 == 3) Serial.println(“nao e isto”);

}
void loop(){}




Que aparece?

O que aparece é o seguinte “?!Hĝ¸?!Ì”
o PK3, 4, e 5 são os pinos A11, A12 e A13 do mega

Isso deve ser indicação suficiente que o problema está aí…

//PORTC |= (1 << 5) | (1 << 4) | (1 << 3); //button pullup resistors
	PORTK |= (1 << 5) | (1 << 4) | (1 << 3); // Alteração

Se mudares para isto, que acontece?

bubulindo:
Isso deve ser indicação suficiente que o problema está aí…

//PORTC |= (1 << 5) | (1 << 4) | (1 << 3); //button pullup resistors
PORTK |= (1 << 5) | (1 << 4) | (1 << 3); // Alteração



Se mudares para isto, que acontece?

Também já experimentei assim, mas não funciona como devia, mas começo a ter duvidas que o problema esteja nos botões, porque parece haver alguma reacção nesses botões, idêntico a um reiniciar do processo, provavelmente há outra coisa que está a provocar isso.
Talvez só mesmo alguém experiente com o mega, possa descortinar os problemas.

Obrigada
José Rodrigues

Isto é interessante...

Ou seja, tu assumes que o problema está nos botões, dizes-me que o problema está nos botões e depois quando vamos a ver que tens outra coisa que está mal, dizes que o problema é falta de experiência de quem te ajudou?

Assim vais longe...

Qual é mesmo o problema? E deixa a tua opinião sobre o que o causa de parte se queres que alguém to descubra.

bubulindo:
Isto é interessante…

Ou seja, tu assumes que o problema está nos botões, dizes-me que o problema está nos botões e depois quando vamos a ver que tens outra coisa que está mal, dizes que o problema é falta de experiência de quem te ajudou?

Assim vais longe…

Qual é mesmo o problema? E deixa a tua opinião sobre o que o causa de parte se queres que alguém to descubra.

Peço desculpa se foi isso que entendeu, mas não era essa a intenção, quem não tem experiência nenhuma sou eu, por isso falei numa pessoa com mais experiência no mega, alguém que consiga olhar para o código e ver onde está o problema ou problemas.
Não quero menosprezar o seu conhecimento, nem de ninguém aqui no forum, todas as ajudas são bem vindas.
O meu problema está exactamente, em saber qual é o problema, só mesmo olhando para o tudo é que poderão encontrar.

Mais uma vez as minhas desculpas.
José Rodrigues

josemapiro:
O meu problema está exactamente, em saber qual é o problema, só mesmo olhando para o tudo é que poderão encontrar.

Não é assim que isto funciona. Olhar para um código e descobrir o problema é sorte. O problema é descoberto através de sintomas. Quando vais ao médico, ele descobre o teu mal sem falar contigo ou olhar para ti?

Então em vez de nos dizeres para olhar em 1500 linhas de código a ver se descobrimos alguma coisa, deverias comecar por dizer o que é que acontece de errado com o teu sistema. Se dizes que não funciona, é porque algo em específico não está a funcionar.

Se dizes que suspeitas que ele faz um reset, é porque algo em específico te indica isso…

Até um vídeo do sistema a falhar serve para termos uma pequena ideia do que pode estar a acontecer e do que podes fazer para descobrir exactamente o problema. Agora dizer para olharmos em 1500 linhas de código é pedir demais.

Ora bom o Programa não sei se já viu, é para utilizar no carro, de forma a informar o consumo instantâneo e outras informações ligadas ao mesmo, inicialmente pretendia ir para o OBDuino, porque me pareceu ser melhor, mas só depois de ter comprado o material e algumas tentativas falhadas, é que vi que só funciona em carros com OBDII, o que não é o caso do meu. Alternativas só o MPGuino, que começou por ser construído para o atmega 168 e posteriormente adaptado ao atmega 328. Iniciei as ligações como descrito no esquema, e fiz o update do código para o atmega2560, e não mostrava nada no visor, era como se estivesse desligado. Procurei ver qual era o problema e verifiquei que as portas que tinha definidas para o atmega 328, algumas eram diferentes no atmega 2560, o que me ocorreu foi, vou alterar as portas para o atmega2560. Vi qual era a forma que utilizava para definir as portas e comecei a alterar, e obtive algum sucesso coloquei o visor a funcionar direito, mas quando fui a percorrer os menus, verifiquei que não funcionavam, premia os botões e nada acontecia, dai eu suspeitar que o problema estava nos botões. Tentei varias formas mas sempre falhava, uma duvida que tenho, é se as portas tiverem todas corretas, o restante código, funciona em qualquer um dos atmegas, ou também tem que ser alterado para o atmega2560. Este é o video onde mostra o reinicio. http://www.youtube.com/watch?v=N1XmgMJ-PTY

Obrigada José Rodrigues

Em principio, se as portas estiverem correctas, o código deve funcionar... mas é preciso ter cuidado com alguns registos que podem ter valores diferentes. Pode ser esse o problema que estás a ver.

Qual é o botão e que carregas para isto acontecer? Ou acontece com qualquer um dos botões?

bubulindo: Em principio, se as portas estiverem correctas, o código deve funcionar... mas é preciso ter cuidado com alguns registos que podem ter valores diferentes. Pode ser esse o problema que estás a ver.

Qual é o botão e que carregas para isto acontecer? Ou acontece com qualquer um dos botões?

Acontece com qualquer um dos botões.

Estas são as portas que estavam definidas no código a frente tem as portas correspondentes no mega e depois as portas que defini. Vehicle interface pins Pins Mega Alteração Pins injector open D2 (int0) 19 PE4 INT4 2 injector closed D3 (int1) 18 PE5 INT5 3 speed C0 (pcint8) 37 PK0 PCINT16 62

LCD Pins DI D4 não existe PG5 4 DB4 D7 não existe PH4 7 DB5 B0 53 PH5 8 DB6 B4 10 PB6 12 DB7 B5 11 PB7 13 Enable D5 não existe PE3 5 Contrast D6, controlled by PWM on OC0A não existe PH3 6 Brightness B1, controlled by PWM on OC1A 52 PH6 9

Buttons left C3 (pcint11) 34 PK3 PCINT19 65 middle C4 (pcint12) 33 PK4 PCINT20 66 right C5 (pcint13) 32 PK5 PCINT21 67

Nota: apesar de existir os pins PC0, PC3, PC4, PC5, PD2, PD3 e PB1, algumas funções não existem ou estão em outros pins, como é o caso do PCINT8,PCINT11, PCINT12, PCINT13, INT0, INT1, OC0A e OC1A, de referir tambem que os pins PCx são Digitais e não analogicos, como acontecia com o atmega 328.

Espero que ajude Mais uma vez Obrigada José Rodrigues

Esses “não existe” indicam o quê??

Tens aí um tal de INT0 e INT1 que ligavam ao D2 e D3 e agora estão noutros pinos. Mudaste isto:

volatile static pFunc int0Func;
ISR(INT0_vect)                                  //mudar para INT4
{ //processInjOpen by default
        int0Func();
}

volatile static pFunc int1Func;
ISR(INT1_vect)                                //Mudar para INT5
{//processInjClosed
        int1Func();
}

Mudaste isto:

void enableLButton() {
        PCMSK1 |= (1 << PCINT11);
}
void enableMButton() {
        PCMSK1 |= (1 << PCINT12);
}
void enableRButton() {
        PCMSK1 |= (1 << PCINT13);
}

E isto?

ISR( PCINT1_vect )
{
        static byte vsspinstate = 0;
        byte p = PINC;//bypassing digitalRead for interrupt performance
        if ((p & vssBit) != (vsspinstate & vssBit)) {
                addEvent(enableVSSID, parms[vsspauseIdx]); //check back in a couple milli
        }
        if (lastVssFlop != vssFlop) {
                lastVSS1 = lastVSS2;
                unsigned long t = microSeconds();
                lastVSS2 = elapsedMicroseconds(lastVSSTime, t);
                lastVSSTime = t;
                tmpTrip.vssPulses++;
                tmpTrip.vssPulseLength += lastVSS2;
                lastVssFlop = vssFlop;
        }
        vsspinstate = p;
        buttonState &= p;
}

Isto:

       //set up the external interrupts
        EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01)))
                        | ((parms[injEdgeIdx] == 1 ? RISING : FALLING) << ISC00);
        EIMSK |= (1 << INT0);
        EICRA = (EICRA & ~((1 << ISC10) | (1 << ISC11)))
                        | ((parms[injEdgeIdx] == 1 ? FALLING : RISING) << ISC10);
        EIMSK |= (1 << INT1);

        PORTC |= (1 << 5) | (1 << 4) | (1 << 3); //button pullup resistors

Isto:

//low level interrupt enable stuff
        PCMSK1 |= (1 << PCINT8);
        enableLButton();
        enableMButton();
        enableRButton();
        PCICR |= (1 << PCIE1);

E isto:

#define lbuttonBit ( 1 << 3 )
#define mbuttonBit ( 1 << 4 )
#define rbuttonBit ( 1 << 5 )

Isto:

 byte p = PINC;//bypassing digitalRead for interrupt performance

Assim de repente não vejo mais nada que influencie com os botões. Dá uma vista de olhos nestes sítios e vê se realmente o que tens montado na tua placa condiz com isto.

Detetei agora, que se utilizar a alteração que fiz para o int0 e int1, o lcd mostra apenas o "OpenGauge MPGuino V0.86 e fica parado ali, se utilizar os botões não tem qualquer efeito, se não utilizar as alterações, mostra como no video como no video.

Este é o código referente a esta parte.

unsigned volatile long instInjStart = nil;
unsigned volatile long tmpInstInjStart = nil;
unsigned volatile long instInjEnd;
unsigned volatile long tmpInstInjEnd;
unsigned volatile long instInjTot;
unsigned volatile long tmpInstInjTot;
unsigned volatile long instInjCount;
unsigned volatile long tmpInstInjCount;

volatile static pFunc int0Func;
//volatile static pFunc int4Func;  // Alteração
ISR(INT0_vect)
//ISR(INT4_vect)  // Alteração
{ //processInjOpen by default
	int0Func();
	//int4Func();  // Alteração
}

volatile static pFunc int1Func;
//volatile static pFunc int5Func;  // Alteração
ISR(INT1_vect)
//ISR(INT5_vect)  // Alteração
{//processInjClosed
	int1Func();
	//int5Func();  // Alteração
}

void processInjOpen(void) {
	injHiStart = microSeconds();
}

void processInjClosed(void) {
	long t = microSeconds();
	long x = elapsedMicroseconds(injHiStart, t) - injectorSettleTime;
	if (x > 0)
		tmpTrip.injHius += x;
	tmpTrip.injPulses++;

	if (tmpInstInjStart != nil) {
		if (x > 0)
			tmpInstInjTot += x;
		tmpInstInjCount++;
	} else {
		tmpInstInjStart = t;
	}

	tmpInstInjEnd = t;
}

volatile boolean vssFlop = 0;

void enableVSS() {
	//    tmpTrip.vssPulses++;
	vssFlop = !vssFlop;
}






MAIS EM BAIXO NO CODIGO





        injectorSettleTime = injhold;
	int0Func = processInjOpen;
	//int4Func = processInjOpen;  // Alteração
	int1Func = processInjClosed;
        //int5Func = processInjClosed;  // Alteração

	//set up the external interrupts
	EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01)))
			| ((parms[injEdgeIdx] == 1 ? RISING : FALLING) << ISC00);
	EIMSK |= (1 << INT0);
	//EIMSK |= (1 << INT4);  // Alteração
	EICRA = (EICRA & ~((1 << ISC10) | (1 << ISC11)))
			| ((parms[injEdgeIdx] == 1 ? FALLING : RISING) << ISC10);
	EIMSK |= (1 << INT1);
	//EIMSK |= (1 << INT5);  // Alteração






AINDA MAIS EM BAIXO






        void initGuino() { //edit all the parameters
	for (int x = 0; x < parmsLength; x++)
		editParm(x);
	save();
	injectorSettleTime = injhold;

	int0Func = processInjOpen;
	//int4Func = processInjOpen;  // Alteração
	int1Func = processInjClosed;
	//int5Func = processInjClosed;  // Alteração
	EIMSK &= ~(1 << INT0);
	//EIMSK &= ~(1 << INT4);  // Alteração
	EIMSK &= ~(1 << INT1);
	//EIMSK &= ~(1 << INT5);  // Alteração

	EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01)))
			| ((parms[injEdgeIdx] == 1 ? RISING : FALLING) << ISC00);
	EIMSK |= (1 << INT0);
	//EIMSK |= (1 << INT4);  // Alteração
	EICRA = (EICRA & ~((1 << ISC10) | (1 << ISC11)))
			| ((parms[injEdgeIdx] == 1 ? FALLING : RISING) << ISC10);
	EIMSK |= (1 << INT1);
       // EIMSK |= (1 << INT5);  // Alteração

Obrigada
José Rodrigues

Se tu deres uma vista de olhos em todo esses sítios que indiquei, em princípio descobres o que causa isto.

Onde diz não existe, quero dizer que não tem essas atribuições no atmega 2560, como poderá ver no ficheiro “pins_arduino.h” para o mega, o INT0 e o INT1 no mega é o SCL 21 e SDA 20 o D2 e D3 que são os que estão definidos no código são o INT4 e INT5 no mega.
A minha duvida é se as alterações que fiz estão corretas, porque creio que o int0 e int1 também são utilizados como interrupções em outros pins, corrija-me se estiver errado, o que posso estar a mudar coisas que não devia.
Quanto aos PKx, PEx, PHx, PGx, etc. já alterei todo para a forma que indicou no inicio mas não notei qualquer alteração.
Quanto ao PINC alterei porque não vai usar as portas C mas sim as K.

Aqui não sei como definir;

#define lbuttonBit ( 1 << 3 )
#define mbuttonBit ( 1 << 4 )
#define rbuttonBit ( 1 << 5 )

Aqui alterei o PCMSK1 para PCMSK2 porque vai do PCINT16 ao 23 que são os que defini.

PCMSK1 |= (1 << PCINT8);
        enableLButton();
        enableMButton();
        enableRButton();
        PCICR |= (1 << PCIE1);

Alterei tambem o PCIE1 para PCIE2, porque é o que define as interrupções do PCINT16 ao 23.

Bit 2 – PCIE2: Pin Change Interrupt Enable 1
When the PCIE2 bit is set (one) and the I-bit in the Status Register (SREG) is set (one), pin
change interrupt 2 is enabled. Any change on any enabled PCINT23:16 pin will cause an interrupt.
The corresponding interrupt of Pin Change Interrupt Request is executed from the PCI2
Interrupt Vector. PCINT23:16 pins are enabled individually by the PCMSK2 Register.

Retirado do manual do Atmega 2560

Obrigada
José Rodrigues

Existe alguma maneira de colocares aqui o teu código?

Só assim é que se pode ver as inconsistências. :\

Acho que a maior parte dos sítios onde temos de mexer estão identificados... logo agora é mesmo ir acertando o código. Mas isso só vendo tudo para estarmos a falar da mesma coisa. :\

Agora vou ter que preparar para almoçar, tenho que trabalhar de tarde, mas logo coloco aqui todas as partes do código que alterei, talvez assim se chegue a alguma conclusão.

Obrigada José Rodrigues

Aqui está partes do código onde fiz alterações, tem o código original e a alteração que fiz.
Onde diz que acrescentei, foi o código que copiei de uma versão anterior, algumas partes ainda se mantinham apenas estavam desactivadas,
essas alterações só as fiz, porque não conseguia colocar o brilho do lcd a funcionar, como encontrei uma versão diferente do código que me pareceu ser mais fácil de alterar e optei por essa cituação.

#define ContrastPin 6  // Acrescentei esta alteração
#define BrightnessPin 9  // Acrescentei esta alteração

byte brightness[]={255,214,171,128}; //middle button cycles through these brightness settings
//byte brightness[] = { 0, 41, 84, 128 }; //middle button cycles through these brightness settings
#define brightnessLength (sizeof(brightness)/sizeof(byte)) //array size
byte brightnessIdx = 1;
//event functions

void enableLButton() {
  	//PCMSK1 |= (1 << PCINT11);      // O Original
	PCMSK2 |= (1 << PCINT19);  // A Minha Alteração
}
void enableMButton() {   
  	//PCMSK1 |= (1 << PCINT12);     // O Original
	PCMSK2 |= (1 << PCINT20);  // A Minha Alteração
}
void enableRButton() {
        //PCMSK1 |= (1 << PCINT13);     // O Original
	PCMSK2 |= (1 << PCINT21);  // A Minha Alteração
}
//array of the event functions
pFunc eventFuncs[] = { enableVSS, enableLButton, enableMButton, enableRButton };
#define eventFuncSize (sizeof(eventFuncs)/sizeof(pFunc))
//define the event IDs
#define enableVSSID 0
#define enableLButtonID 1
#define enableMButtonID 2
#define enableRButtonID 3
//ms counters
unsigned int eventFuncCounts[eventFuncSize];

//schedule an event to occur ms milliseconds from now
void addEvent(byte eventID, unsigned int ms) {
	if (ms == 0)
		eventFuncs[eventID]();
	else
		eventFuncCounts[eventID] = ms;
}
//volatile static pFunc int0Func;             // O Original
volatile static pFunc int4Func;        // A minha Alteração
//ISR(INT0_vect)                              // O Original
ISR(INT4_vect)                         // A minha Alteração
{ //processInjOpen by default
	//int0Func();                        // O Original
	int4Func();                   // A minha Alteração
}

//volatile static pFunc int1Func;            // O Original
volatile static pFunc int5Func;       // A minha Alteração
//ISR(INT1_vect)                             // O Original
ISR(INT5_vect)                        // A minha Alteração
{//processInjClosed
	//int1Func();                        // O Original
	int5Func();                   // A minha Alteração
}

void processInjOpen(void) {
	injHiStart = microSeconds();
}

void processInjClosed(void) {
	long t = microSeconds();
	long x = elapsedMicroseconds(injHiStart, t) - injectorSettleTime;
	if (x > 0)
		tmpTrip.injHius += x;
	tmpTrip.injPulses++;

	if (tmpInstInjStart != nil) {
		if (x > 0)
			tmpInstInjTot += x;
		tmpInstInjCount++;
	} else {
		tmpInstInjStart = t;
	}

	tmpInstInjEnd = t;
}