AttachInterrup e Variável Global

Olá pessoal ,

Estou com um problema em um código que utiliza o attch para chamar um void e ele executa uma função.

O problema surge quando o valor de uma variável global (Int) não passa para esse void funcao() , o valor atribui mas a função não consegue ler .

Código:

int valor; // Já tentei colocar volatile e não funcionou

void setup() {

 pinMode(2, INPUT);


  attachInterrupt(0, funcao,RISING);  

}



void loop()  {

  valor = analogRead(A0); // O valor atribui certo aqui

 }
 
 void funcao()  {

   Serial.print(valor); // Mas não consegue ler aqui

}

Pelo que entendi você apenas criou a função mais não chamou ela.
coloque essa parte do codigo antes do loop

void funcao() {

Serial.print(valor); // Mas não consegue ler aqui

}

a e para toda função que você criar você tem que chama-la em algum ponto do programa ex:

void loop() {

valor = analogRead(A0); // O valor atribui certo aqui
funcao();
}

Vê se funciona

Como "rule of the tumb" nunca deves executar nada que demore precioso tempo dentro de uma rotina de interrupçao.As comunicaçoes serie sao muitoooo leeentttasssssss .....
Portanto nao podes fazer isto:

void funcao() {

Serial.print(valor); // Mas não consegue ler aqui

}

A soluçao passa por colocar uma flag dentro da rotina de interrupçao.
Algo isto:

nt valor; 
bool flagDeInterrupcao = false;

void setup() 
{
  pinMode(2, INPUT);
  attachInterrupt(0, funcao,RISING);  
}

void loop()  
{
  valor = analogRead(A0); // O valor atribui certo aqui
  if(flagDeInterrupcao)imprimeValor();
}

void funcao()  
{
  flagDeInterrupcao = true;
}
void imprimeValor()
{
  Serial.print(valor); 
  flagDeInterrupcao = false;
}

Agradeço as respostas ,

André a funçao esta sendo chamada no attach.
Hugo vou tentar e ja mando o resultado.

Obrigado !

A variavel valor nao e inicializada... podias mudar isso tambem...

Como sabes que a interrupcao esta a ser chamada? Tens um LED para poderes testar isso?

A porta serie agora, tanto quanto sei, apenas copia a string que queres enviar para um buffer e activa o envio da string. Isso, apesar de nao ser rapido, nao e propriamente demorada. Antigamente, nao era assim que funcionava e o comentario do Hugo fazia muito mais sentido.

Como ligaste o botao? Tens um pull up?

Eu aposto que a interrupcao nunca e activada... :slight_smile:

É ,

magicamente bubulindo adivinhou, a função não estava sendo chamada mesmo . Devido a uma biblioteca que estava configurada para usar justo o pino 2 do attach para outra função, havia o conflito mas passava na compilação .Troquei para attach 1 (pino 3 ) e resolveu o problema da execução , mas aproveito para deixar outra questão para poderem me ajudar.

O código aprimorado agora se trata de um dimmer Ac com controle DMX(RS485) por uma biblioteca .

O problema apresentado é que posso dizer que arduino esta sem "tempo" para ler o dmx antes que o attach é chamado novamente.

Como todo dimmer ac feito no arduino, utilizamos um attach para poder ter a referencia do cross 0 ( inicio da senoide) e assim disparar o triac um tempo depois para pegar a amplitude desejada da onda. Até ai tudo certo ,mas o bug vem quando o arduino tem que fazer a leitura do DMX e o attach é chamado ao mesmo tempo. A impressão que da é que a função de leitura do DMX não é terminada completamente e o valor retornado é desconhecido .Assim gerando um mal funcionamento no corte da onda.

Código :

#include <DMXSerial.h>

int triac = 13;
int dimming = 0; 
int dimtime = 0;

void setup() {
  
  DMXSerial.init(DMXReceiver);
 
  pinMode(triac, OUTPUT);
  
  attachInterrupt(1, zerocross,RISING);  

}

void zerocross()  {

  dimtime = (69*dimming);    
  delayMicroseconds(dimtime);   
  digitalWrite(triac, HIGH);  
  delayMicroseconds(8.33);                                   
  digitalWrite(triac, LOW);  

}

void loop()  {
  
dimming = map(DMXSerial.read(1),0,255,115,5);

 }

O código é basicamente isso o loop realiza a leitura do DMX e mapeia para um intervalo de numeros validos para a construção do tempo de disparo da onda. Porem não funciona na pratica, a lampada fica piscando descontroladamente . Posso perceber que deve haver algum problema com a biblioteca DMX pois só de colocar o termo DMXSerial.read(1) no loop sem ter nenhum relacionamento com a variável a execução já apresenta o bug.

Biblioteca

DMXSerial.h :

// - - - - -
// DMXSerial - A hardware supported interface to DMX.
// DMXSerial.h: Library header file
// 
// Copyright (c) 2011 by Matthias Hertel, http://www.mathertel.de
// This work is licensed under a BSD style license. See http://www.mathertel.de/License.aspx
// 
// Documentation and samples are available at http://www.mathertel.de/Arduino
// 25.07.2011 creation of the DMXSerial library.
// 01.12.2011 include file changed to work with the Arduino 1.0 environment
// 10.05.2012 added method noDataSince to check how long no packet was received
// - - - - -

#ifndef DmxSerial_h
#define DmxSerial_h

#include <avr/io.h>

// ----- Constants -----

#define DMXSERIAL_MAX 512 // max. number of supported DMX data channels

#define DmxModePin 2     // Arduino pin 2 for controlling the data direction
#define DmxModeOut HIGH  // set the level to HIGH for outgoing data direction
#define DmxModeIn  LOW   // set the level to LOW  for incomming data direction

// ----- Enumerations -----

// Mode of Operation
typedef enum { 
  DMXNone, // unspecified
  DMXController, // always sending
  DMXReceiver    // always listening
} DMXMode;

// ----- Library Class -----

class DMXSerialClass
{
  public:
    // Initialize for specific mode.
    void    init       (int mode);

    // Set the maximum used channel for DMXController mode.
    void    maxChannel (int channel);

    // Read the last known value of a channel.
    uint8_t read       (int channel);

    // Write a new value of a channel.
    void    write      (int channel, uint8_t value);

    // Calculate how long no data backet was received
    unsigned long noDataSince();

    // Terminate operation.
    void    term       (void);
};

// Use the DMXSerial library through the DMXSerial object.
extern DMXSerialClass DMXSerial;

#endif

Acredito que o bug anterior de não chamar a função é de referencia ao " #define DmxModePin 2 "

DMXSeria.cpp : Não deu pra colocar aqui devido ao tamanho .

Link: ViniciusTech / Códigos / commit / 7e28a8176dd1 — Bitbucket

Sei que a explicação ficou grande e cansativa mas espero que possam me ajudar.

Agradeço desde já.