Interupts aren't working

Hello, I would like the voltage output by the DAC to change when I switch pin 1. I am currently simulating this change by switching between GND and 3 V on the plug-in board. This is my code (I use the Nano Every):

#include <Wire.h>
#include <MCP4726.h>
float vref = 4840;
MCP4726 dac;

volatile int x = 0;
int pin1 = A0;
int pin2 = A1;
int pin3 = A2;

void fall() {
  dac.setVoltage(x);
  x += 500;
  if (x >= 4096) {
    x = 0;
  }
}



void setup() {
  // For MCP4726 the address is 0x60 (A0 part address. Check MCP4726 part number suffix as address could be different)
  dac.begin(MCP4726_DEFAULT_ADDR);
  pinMode(12, OUTPUT),
  digitalWrite(12, HIGH);
  Serial.begin(9600);
  pinMode(pin1,INPUT);
  attachInterrupt(digitalPinToInterrupt(pin1), fall, CHANGE);
}

crossposting

1 Like

First of all: what is not working? Your code is not complete (no loop())!
To read a switch, an interrupt handler is usually the wrong way. For example, sending an I2C message inside an interrupt handler is a bad idea. Generally you shouldn't use any method depending on interrupts to work inside an interrupt handler.

So, if you need more help, post a wiring diagram of your setup, post your complete code and post a link to the library used (as it doesn't seem to be available in the library manager of the IDE)!

Here is my full code:

#include <Wire.h>
#include <MCP4726.h>

MCP4726 dac;

// name pins
const byte ADMUX0 = A0;
const byte ADMUX1 = A1;
const byte ADMUX2 = A2;

int SW = 9;               // Switch for VDD
int LED = 10;             // LED       
int MUXmain = 12;         // Multiplexer on mainboard 
int vdd_pin = A7;

volatile int index;  // variable for binary 

float vref;


const byte NUM_CHANNELS = 8; //Number of Channels
volatile float voltages[NUM_CHANNELS];  //array for set voltages

byte calculateIndex(byte pin0, byte pin1, byte pin2) {
  return (digitalRead(pin0) ? 1 : 0) * 1 + (digitalRead(pin1) ? 1 : 0) * 2 + (digitalRead(pin2) ? 1 : 0) * 4;
}

void printncompare() {
  const char* channelNames[] = {"TC", "O2", "CO", "PRESS", "COLD", "TEMP_O2", "TEMP_CO", "TEMP_PRESS"};
  Serial.println("Current set voltages of all channels:");
  
  for (int i = 0; i < NUM_CHANNELS; i++) {
    Serial.print(channelNames[i]);
    Serial.print(": ");
    Serial.print(voltages[i], 4);
    Serial.println(" V");
  } 
  Serial.println();
}

int current_chnnel;

void chng_mux() {
  index = calculateIndex(ADMUX0, ADMUX1, ADMUX2);
  dac.setVoltage(voltages[index]);
  current_channel = index;
}

void set_val_zero() {
  volatile float voltages[NUM_CHANNELS] = {1270, 2274, 1225, 1225, 987.7, 1225, 1225, 1225};
}

void prepareSim() {
  Serial.println("Device connected");
  digitalWrite(LED, HIGH);
  digitalWrite(MUXmain, HIGH);
}

void setup() {
  pinMode(ADMUX0, INPUT);
  pinMode(ADMUX1, INPUT);
  pinMode(ADMUX2, INPUT);
  pinMode(vdd_pin, INPUT);
  Serial.begin(9600);
  attachInterrupt(ADMUX0, chng_mux, CHANGE);
  attachInterrupt(ADMUX1, chng_mux, CHANGE);
  attachInterrupt(ADMUX2, chng_mux, CHANGE);
  dac.begin(MCP4726_DEFAULT_ADDR);
}

void loop() {
  float vdd_value = analogRead(vdd_pin);
  vref = vdd_value * (5.0 / 1024.0); //Caution: The value '5.0' must be adjusted if the operating voltage is not equal to 5.0 V
    if (vdd_value > 3.0) {
      prepareSim();
      Serial.println("Which signal should be changed?");
      
      while (Serial.available() == 0); // Überprüfung, ob Daten über die serielle Schnittstelle verfügbar sind
      char input[20];  // Array zur Speicherung der Eingabe
      Serial.readStringUntil('\n').toCharArray(input, sizeof(input));  // Lesen der seriellen Daten in den char-Array
      while (Serial.available() > 0) Serial.read();  // das leert den Buffer
      
      const char* channelNames[] = {"TC", "O2", "CO", "PRESS", "COLD", "TEMP_O2", "TEMP_CO", "TEMP_PRESS"};
      int channelIndex = -1;
      
      for (int i = 0; i < sizeof(channelNames) / sizeof(channelNames[0]); i++) {
        if (strcmp(input, channelNames[i]) == 0) {
          channelIndex = i;
          break;
      }
    }
    
    if (channelIndex != -1) {
      Serial.println("Which voltage value should be set?");  // Prompt User for input
      while (Serial.available() == 0);
      float voltage = Serial.parseFloat();
      while (Serial.available() > 0) Serial.read();  // das leert den Buffer
      
      if (voltage <= vref) {
        voltages[channelIndex] = voltage;
      } else {
        Serial.println("Error. Voltage value exceeds Vref.");
      }
    } else {
      Serial.println("Error. Unknown signal");
    }
    printncompare();
    }
    else {
      digitalWrite(LED, LOW);
      digitalWrite(SW, LOW);
      Serial.println("Measuring device is not connected!");
      Serial.println(vdd_value);
      delay(1500);
    }
     
}

The arduino documents recommend using digitalPinToInterrupt(pin)

attachInterrupt(digitalPinToInterrupt(pin), ISR, mode)

Do you please answer my first question?

The OP did that, at least in the first post. But you're right, it doesn't increase trust if it disappears when posting complete code.

1 Like

You can not use i2c communications inside an ISR. i2c requires interrupts, and they are disabled inside the isr. You will need to set a flag and respond to it in loop() or else don't use an interrupt to read the change of the input pin.

@derahnungslose,

This Topic has been locked as it is the identical or too similar your other topic.

Please do not duplicate your questions as doing so wastes the time and effort of the volunteers trying to help you as they are then answering the same thing in different places.

Please create one topic only for your question and choose the forum category carefully. If you have multiple questions about the same project then please ask your questions in the one topic as the answers to one question provide useful context for the others, and also you won’t have to keep explaining your project repeatedly.

Repeated duplicate posting could result in a temporary or permanent ban from the forum.

Could you take a few moments to Learn How To Use The Forum

It will help you get the best out of the forum in the future.

Thank you.