About Arduino Interrupts

Originally, this thread title was: "(double) read multiple digital pins" but I change it.
Hello o/
In sumary; I run a program to read some parallel pins in Proteus simulator. When I cycle through the pins, this program reads them, and output to a virtual terminal a response. But sometimes, it is outputting 2 times for the same reading. I put an osciloscope on the sending data pins and NO bouncing or double signal is sent to the arduino inputs. But I can see on the terminal the double results (randomly). So the double output is definitely from the arduino program.
It can be anything, a second pair of eyes is always good. Thank you !


image

The program:

#include "Arduino.h"

void setup() {
Serial.begin(9600);

pinMode(13, INPUT);
pinMode(12, INPUT);
pinMode(11, INPUT);
pinMode(10, INPUT);

}

int pin13State = 0;
int pin12State = 0;
int pin11State = 0;
int pin10State = 0;
int lastpin13State = 0;
int lastpin12State = 0;
int lastpin11State = 0;
int lastpin10State = 0;

bool isNotaccessedAlready=true;

void loop() {

pin13State = digitalRead(13);
pin12State = digitalRead(12);
pin11State = digitalRead(11);
pin10State = digitalRead(10);
  
isNotaccessedAlready=true;
if (pin13State != lastpin13State || pin12State != lastpin12State || pin11State != lastpin11State || pin10State != lastpin10State) 
{
  if(isNotaccessedAlready)
  {
    isNotaccessedAlready=false; // used for possible double readings from the || operators inside this if
    Serial.print(Binaryread());
    Serial.println();
    
    lastpin13State=pin13State;
    lastpin12State=pin12State;
    lastpin11State=pin11State;
    lastpin10State=pin10State;
    return;
  }
}

}


int sum = 0;
int Binaryread()
{
  sum=0;
  if (digitalRead(13) == HIGH)  sum += 1; 
  if (digitalRead(12) == HIGH)  sum += 1;  
  if (digitalRead(11) == HIGH)  sum += 1;   
  if (digitalRead(10) == HIGH)  sum += 1;
  return(sum);
}



bool IsChanged()//this function is not used in the code anymore
{
  if (digitalRead(13)==LOW || digitalRead(12)==LOW || digitalRead(11)==LOW || digitalRead(10)==LOW)  
  return(true);
}
1 Like

don't worry about simulators issues. stay focused on important things.
read about port manipulation

I really don't understand your answer.
Please check the code and see if you spot any possible error from my part. OR come with some tweak of the code I don't know. Thank you.

1 Like

On an AVR processor like the Uno, read all pins from a port using direct port access, for example:

byte x = PIND: //PORTD digital pins 0-7

1 Like

ok, I made a new function using your code:

int Binaryread2()
{
byte x = PIND; //PORTD digital pins 0-7
return(x);
}

and inside the loop code I used it as:

  Serial.print(Binaryread2());

for these tests here Im --always-- reseting the terminal


I reset the terminal and those 3and1 was the output for that sequence in the signal

Again, I reset the terminal and that number is for that input.
image

Very strange results !!! I dont get them.

1 Like

Which Arduino are you assuming? On the Uno, these pins are on port B.

pinMode(13, INPUT);
pinMode(12, INPUT);
pinMode(11, INPUT);
pinMode(10, INPUT);

To read those pins, use PINB.

Is port D set to INPUT?

What are the actual values of the inputs on port D, which is what you are reading?

I can't make much sense of your diagram, or connect it to your question.

1 Like

Read the original code I posted. Everything is mentioned there.

I used :

pinMode(13, INPUT);
pinMode(12, INPUT);
pinMode(11, INPUT);
pinMode(10, INPUT);

but I might see your error:
image
you said portD, probably is portB that I should use.

byte x = **PINB**: //<<<< right?
1 Like

I made the necessary correction

int Binaryread2()
{
byte x = PINB; //PORTB digital pins 8-13
return(x);
}

and now I got some NEW data output to the terminal:


new reading

but --RANDOMLY-- I get some double results !!! -like in this img:
(it should have being only 1one 21 result, not 2 of them. You get me.

I am using ARDUINO UNO R3 in the simulator.

I think the problem is that you are using return in the loop().
It breaks the whole logic of your program. Remove the return, it is not needed in your code

2 Likes

Probably is harder to see the problem code in this relatively big code. Is not that big though. But here is the problem location:
I believe those OR operators || are read one after another and if let's say [pin12State != lastpin12State], it will perform an entire if statement code execution, then return to the NEXT || operator in line , this time will be [pin11State != lastpin11State], and again, if found !=, it will perform an entire if statement code execution (again).
This is my explanation that I can think of.

isNotaccessedAlready=true;
if (pin13State != lastpin13State || pin12State != lastpin12State || pin11State != lastpin11State || pin10State != lastpin10State) 
{
  if(isNotaccessedAlready)
  {
    isNotaccessedAlready=false; // used for possible double readings from the || operators inside this if
....
  }
....
    return;
  }
}

Also this flag is absolutely useless:

Heh, it works --the same-- with or without it ! Very strange, it is having no impact on the code.
I specifically search for a code break and all I found was the return keyword for -if- statements.
Originally, I didnt include this return and it was doing the same exact thing as now.
After including the return, it is still doing the same thing as before, no change.
Very strange.... right?

this should not lead to duplication, because you remember the changes of all four signals each time

that is not a flag.
That is a boolean variable I created. In the hope it will split the potential double code execution inside the if statement from multiple OR || operators.
It is a wild guess, but it didnt work either. It didnt helped. So yes, in a sense, it is useless NOW after I tested it.

Ok, try to change this

this way:

int Binaryread()
{
  sum=0;
  if (pin13State== HIGH)  sum += 1; 
  if (pin12State== HIGH)  sum += 1;  
  if (pin11State== HIGH)  sum += 1;   
  if (pin10State == HIGH)  sum += 1;
  return(sum);
}

Such boolean variables in programming are usually called flags.

So here is a osciloscope reading on the data Input lines:
(if you dont believe me)

I didn't say I didn't believe you.
Just try to replace your Binaryread() function with mine from post 16 and check the result

I tried your new code and I got MORE weird results

  • interesting approach on your code! I didnt see it ! Very good. But still didnt resolve the problem.