Using 0V interrupt pins

Hello, i am Using the Pins 2,3,18,19,20 and 21 as Interrupt pins on an Arduino Mega 2560. I want to activate them in the Program when the Signal on the Pin is 0v, the Pins are currently connected to optocouplers that send a 5v signal to the Arduino when there is no Signal on the other End and 0v when there is a Signal. The Ground from the Arduino is connected to the Optocouplers. I tested the Program before just by connecting the Ground from the Arduino to the Pins and it worked but now when i connect it to the Optocouplers, they are sending points, even though there are 5 Volts connected to the interrupt pins. Can i set the Voltage for the Interrupt pins to Activate, for Example below 0,5 Volts. This is my Code below. Thank you for your answers

/* Settings Area */

/* Input Pins */
#define INI_PIN1 2
#define INI_PIN2 3
#define INI_PIN3 18
#define INI_PIN4 19
#define INI_PIN5 20
#define INI_PIN6 21

/* OUTPUT Pins */
#define RELAIS1 22
#define RELAIS2 23
#define RELAIS3 24
#define RELAIS4 25
#define RELAIS5 26

#define minWheelSpin 200
#define maxWheelSpin 2000

int Relais1Zeit = 0;
int Relais2Zeit = 0;
int Relais3Zeit = 0;
int Relais4Zeit = 0;
int Relais5Zeit = 0;

int GameStarted = 0;
#define BAUDRATE 500000

const int numPins = 6;
const int pins[numPins] = { 2, 3, 18, 19, 20, 21 };
const int Reifenpins[5] = { 22, 23, 24, 25, 26 };
const int points[numPins] = { 100, 50, 75, 100, 25, 0 };
bool pinStates[numPins] = { false };
int activeInis[numPins] = {};
int reifen0zeit = 0;
int reifen1zeit = 0;
int reifen2zeit = 0;
int reifen3zeit = 0;
int volatile IniStateISR = 0;  // Changed inside ISR

struct RelayType {
  int Output;  // OUTPUT PIN
  int State;   // Current State ON / OFF
  int IniState;
  long CurrentTime;  // How Long Relay is already on
  long OnTime;       // How Long the Relay should be on
};

RelayType REL1 = { RELAIS1,
                   0,
                   0,
                   0,
                   0 };
RelayType REL2 = { RELAIS2,
                   0,
                   0,
                   0,
                   0 };
RelayType REL3 = { RELAIS3,
                   0,
                   0,
                   0,
                   0 };
RelayType REL4 = { RELAIS4,
                   0,
                   0,
                   0,
                   0 };

RelayType REL5 = { RELAIS5,
                   0,
                   0,
                   0,
                   0 };

void setup() {
  pinMode(REL1.Output, OUTPUT);
  pinMode(REL2.Output, OUTPUT);
  pinMode(REL3.Output, OUTPUT);
  pinMode(REL4.Output, OUTPUT);
  pinMode(REL5.Output, OUTPUT);
  Serial.begin(BAUDRATE);
  pinMode(INI_PIN1, INPUT_PULLUP);
  pinMode(INI_PIN2, INPUT_PULLUP);
  pinMode(INI_PIN3, INPUT_PULLUP);
  pinMode(INI_PIN4, INPUT_PULLUP);
  pinMode(INI_PIN5, INPUT_PULLUP);
  pinMode(INI_PIN6, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(INI_PIN1), Ini1, RISING);
  attachInterrupt(digitalPinToInterrupt(INI_PIN2), Ini2, RISING);
  attachInterrupt(digitalPinToInterrupt(INI_PIN3), Ini3, RISING);
  attachInterrupt(digitalPinToInterrupt(INI_PIN4), Ini4, RISING);
  attachInterrupt(digitalPinToInterrupt(INI_PIN5), Ini5, RISING);
  attachInterrupt(digitalPinToInterrupt(INI_PIN6), Ini6, FALLING);
}

void Ini1() {
  IniStateISR = 1;
}

void Ini2() {
  IniStateISR = 2;
}

void Ini3() {
  IniStateISR = 3;
}

void Ini4() {
  IniStateISR = 4;
}

void Ini5() {
  IniStateISR = 5;
}

void Ini6() {
  IniStateISR = 6;
}

void StartGame() {
  if (Serial.available() > 0) {
    //String lesen = Serial.readString();
    //Serial.println(lesen);
    if (Serial.readStringUntil('\n') == "GO") {
      Serial.println("Spiel gestartet");
      GameStarted = 1;
      REL5.State = 1;
      IniStateISR = 0;
    }
  }
}

void checkAndSendSignal() {
  if (IniStateISR == 1) {
    IniStateISR = 0;
    Serial.println("50");
    REL1.IniState = 1;
  }
  if (IniStateISR == 2) {
    IniStateISR = 0;
    Serial.println("100");
    REL2.IniState = 1;
  }
  if (IniStateISR == 3) {
    IniStateISR = 0;
    Serial.println("250");
    REL3.IniState = 1;
  }
  if (IniStateISR == 4) {
    IniStateISR = 0;
    Serial.println("500");
    REL4.IniState = 1;
  }
  if (IniStateISR == 5) {
    IniStateISR = 0;
    Serial.println("1000");
  }
  if (IniStateISR == 6) {
    IniStateISR = 0;
    Serial.println("0");
    REL1.State =  0;
    REL2.State =  0;
    REL3.State =  0;
    REL4.State =  0;
    REL5.State =  0;
    GameStarted = 0;
  }
}

void SetRandomTime() {
  /* Set Random time if Ini is detected and Tire is not already spinning */
  if (REL1.IniState == 1 && REL1.State == 0) {
    REL1.OnTime = random(minWheelSpin, maxWheelSpin);
    REL1.CurrentTime = millis();
    REL1.IniState = 0;  // Set to 1 to prevent endless spinning
    REL1.State = 1;     // Set to 1 if Tire spins
  }
  if (REL2.IniState == 1 && REL2.State == 0) {
    REL2.OnTime = random(minWheelSpin, maxWheelSpin);
    REL2.CurrentTime = millis();
    REL2.IniState = 0;  // Set to 1 to prevent endless spinning
    REL2.State = 1;     // Set to 1 if Tire spins
  }
  if (REL3.IniState == 1 && REL3.State == 0) {
    REL3.OnTime = random(minWheelSpin, maxWheelSpin);
    REL3.CurrentTime = millis();
    REL3.IniState = 0;  // Set to 1 to prevent endless spinning
    REL3.State = 1;     // Set to 1 if Tire spins
  }
  if (REL4.IniState == 1 && REL4.State == 0) {
    REL4.OnTime = random(minWheelSpin, maxWheelSpin);
    REL4.CurrentTime = millis();
    REL4.IniState = 0;  // Set to 1 to prevent endless spinning
    REL4.State = 1;     // Set to 1 if Tire spins
  }
}

void spinRandomTire(int relayNumber) {
  if (relayNumber == 1) {
    if (REL1.IniState == 0 && REL1.State == 0) {

      REL1.OnTime = random(minWheelSpin, maxWheelSpin);
      REL1.IniState = 0;  // Set to 1 to prevent endless spinning
      REL1.State = 1;     // Set to 1 if Tire spins
      REL1.CurrentTime = millis();
    }
  }

  if (relayNumber == 2) {
    if (REL2.IniState == 0 && REL2.State == 0) {

      REL2.OnTime = random(minWheelSpin, maxWheelSpin);
      REL2.IniState = 0;  // Set to 1 to prevent endless spinning
      REL2.State = 1;     // Set to 1 if Tire spins
      REL2.CurrentTime = millis();
    }
  }
  if (relayNumber == 3) {
    if (REL3.IniState == 0 && REL3.State == 0) {

      REL3.OnTime = random(minWheelSpin, maxWheelSpin);
      REL3.IniState = 0;  // Set to 1 to prevent endless spinning
      REL3.State = 1;     // Set to 1 if Tire spins
      REL3.CurrentTime = millis();
    }
  }
  if (relayNumber == 4) {
    if (REL4.IniState == 0 && REL4.State == 0) {
      REL4.OnTime = random(minWheelSpin, maxWheelSpin);
      REL4.IniState = 0;  // Set to 1 to prevent endless spinning
      REL4.State = 1;     // Set to 1 if Tire spins
      REL4.CurrentTime = millis();
    }
  }
}

void CheckTime() {
  if (millis() - REL1.CurrentTime >= REL1.OnTime) {
    REL1.State = 0;
  }
  if (millis() - REL2.CurrentTime >= REL2.OnTime) {
    REL2.State = 0;
  }
  if (millis() - REL3.CurrentTime >= REL3.OnTime) {
    REL3.State = 0;
  }
  if (millis() - REL4.CurrentTime >= REL4.OnTime) {
    REL4.State = 0;
  }
}

void SetOutput() {
  digitalWrite(REL1.Output, REL1.State);
  digitalWrite(REL2.Output, REL2.State);
  digitalWrite(REL3.Output, REL3.State);
  digitalWrite(REL4.Output, REL4.State);
  digitalWrite(REL5.Output, REL5.State);
}

void loop() {
  StartGame();
  if (GameStarted == 1) {
    checkAndSendSignal();
    SetRandomTime();

    if (random(0, 30000) == 0) {
      int pin = random(1, 4);
      spinRandomTire(pin);
    }
    SetOutput();
  }
  CheckTime();
}

Please show a circuit diagram of your optocoupler interface and the relay connection.

Why do you think that you need interrupts if you handle the relays in loop()?

Here you undo whatever has previously initialized.

I suggest that you restart with 1 relay and polling. If that works proceed with multiple relays.

1 Like

2000-0200002100031498000100b6-DE.jpg (2000×1657) (wago.com)

A1 is connected to a Sensor that gives a 24 Volt output when its activated, that activates the Optocoupler and it sends 0V, when there is no 24 Volts on the other side, it sends 5 Volts

Das Bild ist leider extrem nichtssagend, mit diesem Modul mußt Du wohl selbst klarkommen. Mit 24V killt man jeden Optokoppler.

Der Optokoppler kann auf jeden fall 24V ab, steht ja auch so in der Dokumentation Optokopplermodul (859-706) | WAGO

Schon besser, mir fehlt aber immer noch der Teil zwischen diesem Modul und dem Mega, ebenso zu den Relais.

Would this topic be more appropriate in the German section of the forum ?

ACK
Yes but I'm not the TO. I can revert to English as well.

Is that a yes ?

A is Connected to the Pins on the Arduino and 0v and 5v also comes from the arduino

If you want them to trigger when it goes from High to Low then change RISING to FALLING

Do you really meed interrupts? If you check many pins 50x per ms and detect and act on changes even while it's still checking. The pins though need to be on the same 8-pin port as all of the pins in the port get read in the same cycle. Last read bit-XOR this read sets result bits where last and this bits differed. XOR = 1 for different, = 0 for same.
Each bit is a different input, HIGH or LOW.
A wire left LOW is more susceptible to EM noise is why signal 0 is inverted.

Is a full set read every 20 or more microseconds close enough?
20 micros is 320 cycles, enough to watch pins take a few small steps IF
there is no blocking code tripping the whole thing up.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.