Why one of the programs in the loop() will randomly activate the relay?

Thread Starter

NewUser2020

Joined Apr 25, 2020
7
Hi All,

I'm using Arduino Nano for this project.

I have two different programs in the loop(). But some how the program 2 will randomly activate the relay, and it will switch the contact pin about 1 sec.

If I comment out either program 1 or 2, It can solved the problem.

Appreciate if can help me solve this problem. Here is the code.

Code:
int PulsePin = 2;
int cutoff1 = 5;
int sensor1 = 6;
int sensor2 = 8;
int led = 9; //pin 9
int i = 0;
int maxCut = 81;
int minCut = 50;
const int PotPin1 = A1;
int Pot1Position_value;
const int potPin2 = A2;
int Pot2Position_value;

long last = 0;
int total = 0;
int total_2;
int count = 0;

int nPalas = 1;
unsigned long Revolutions_per_minute = 0;
int milliseconds = 50;

void setup()
{
  Serial.begin(9600);
  pinMode(PotPin1, INPUT);
  pinMode(potPin2, INPUT);
  pinMode(6, INPUT_PULLUP);
  pinMode(8, INPUT_PULLUP);
  pinMode(cutoff1, OUTPUT);
  digitalWrite(cutoff1, LOW);
  pinMode(PulsePin, INPUT);
}

void loop()
{
  /////// Program 1 ///////
 
  Pot1Position_value = analogRead(PotPin1);
  Pot1Position_value = map(Pot1Position_value, 0, 1023, 1500, 8500);
  //Serial.println(Pot1Position_value);

  total = digitalRead(PulsePin);
  if (total_2 != total)
  {
    if (total == 1 && total_2 == 0)
      count++;
    total_2 = total;
  }
  if (millis() - last >= milliseconds)
  {
    Revolutions_per_minute = (count / nPalas) / 2.0 * 60000.0 / (milliseconds);
    if (Revolutions_per_minute > Pot1Position_value && digitalRead(sensor1) == LOW)
      digitalWrite(cutoff1, HIGH);
    else
      digitalWrite(cutoff1, LOW);
    count = 0;
    last = millis();
  }

/////// Program 2 ///////

  Pot2Position_value = analogRead(potPin2);
  Pot2Position_value = map(Pot2Position_value, 0, 1023, 50, 80);
  //Serial.println(PotPosition_value);

  if (Pot2Position_value > maxCut) {
    Pot2Position_value = maxCut;
  }
  if (Pot2Position_value < minCut) {
    Pot2Position_value = minCut;
  }

  if (digitalRead(sensor2) == HIGH) {
    i = 0;
  }
  if (digitalRead(sensor2) == LOW && i == 0) {
    i += 1;
    cut();
  }
}

void cut() {
  digitalWrite(cutoff1, HIGH);
  digitalWrite(led, LOW);
  delay(Pot2Position_value);
  digitalWrite(cutoff1, LOW);
  digitalWrite(led, HIGH);
}
 

Thread Starter

NewUser2020

Joined Apr 25, 2020
7
I cannot follow the flow of your code.
However, are there limits imposed on the counters?

count++;

i += 1;
Hi @MrChips

Thanks for the reply! There are two different programs.
[Program 2]
i += 1..... Yes. This is to limit the button switch.

[Program 1]
count++; ... This program 1 was copied from somewhere, so I cant really tell what it do.

Seems like these 2 programs cannot put in the loop().... Can help look into it?

Thanks in advance!
 

danadak

Joined Mar 10, 2018
4,057
The program has no coding comments, very poor practice and makes it
very difficult for someone to help. Very poor programming style.

Just a thought.


Regards, Dana.
 

MrSoftware

Joined Oct 29, 2013
2,188
I only glanced briefly, but when I see digital reads in regular code that appear to be intended for control, such as this line:

total = digitalRead(PulsePin);

this is a red flag. This is in the regular loop() part of the code, which means the program will read that pin whenever it happens to get to it. If the pulse is short, you might miss it entirely. If the pulse is long, you might count it multiple times. If you want to catch when a pin changes state, you need to do it by registering an interrupt, then set a flag or increment your counter inside the interrupt routine. You will likely need some mechanism to handle debouncing too. You can do this in code, or you can handle it in hardware, the choice is up to you.
 

jpanhalt

Joined Jan 18, 2008
11,087
I don't do C, so didn't take a close look. As MrSoftware suggests, an interrupt, or just interrupt flag when you are polling, will help, particularly for short pulses. On the other hand, with long pulses compared to loop time, you need to be sure the same pulse isn't counted twice, since a flag will reset the moment it is cleared. There are various ways around that. Having the interrupt/flag based on an edge rather than a state (high/low) may help.
 
Top