Interrupts

Hello everyone,

I'm having a problem trying to call a void fuction by using a button and I think the problem is that I'm not using attachinterrupt function correctly. I'm using arduino UNO and as i saw pins 2 and 3 are used for interrupts. The problem is that when i have 2,3 on pinmode function i can't call _doTare and _doCount. If i put 2 and 3 to the attachInterrupt function i get on the serial monitor COUNT... and TARE... but when i press the buttons still nothing happens.

Here is the code:

#include "HX711.h" //library of scale
//library of rfid
#include <LiquidCrystal.h> //library of lcd

const int resolution=1400;
const int  MaxChars=15;
int val = 0;

String commandChars="~CWL";
char   strValue[MaxChars+1];
char   serialInputType=' ';
float  itemWeight=0.00;
int    index=0;
long   total=0;
long   average = 0;
long   tareWeight=0;
String LCDLine1,LCDLine2;
String itemLabel;
bool doTare=false;
bool doCount=false;

HX711 scale(A4,A3);
LiquidCrystal lcd(7,6,5,4,3,2);
const int BackLight = 8;
void updateLCD () {
   lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(LCDLine1);
  Serial.print("A");
  Serial.println(LCDLine1);
  
  lcd.setCursor(0,1);
  lcd.print(LCDLine2);
  Serial.print("B");
  Serial.println(LCDLine2);
}

long readingAverage(int samples=25,long t=0) {
 total=0;
 
 for (int i=0; i<samples;i++) {
    total=total+((scale.read()/resolution)-t); 
    delay(10);
 }
 return (total / samples);
}

void _doTare() {
  doTare=true;
}

void setTare() {
  doTare=false;
  LCDLine1="TARE ...";
  LCDLine2="";
  updateLCD();
  digitalWrite(13, !digitalRead(13)); // Toggle LED on pin 13
  tareWeight=readingAverage(25,0);
  digitalWrite(13, !digitalRead(13)); // Toggle LED on pin 13
}

void _doCount() {
  doCount=true;
}
void getItemWeight(float c=25.00)
{
  doCount=false;
  LCDLine1="COUNT ...";
  LCDLine2="";
  updateLCD();
  digitalWrite(13, !digitalRead(13)); // Toggle LED on pin 13
  itemWeight=readingAverage(25,tareWeight) / c;
  Serial.print('I');
  Serial.println(int(itemWeight*100));
  digitalWrite(13, !digitalRead(13)); // Toggle LED on pin 13  
}

void setup() {
  
  Serial.begin(9600);
  Serial.println("Counting Scale - Version 0.9");
  pinMode(13, OUTPUT);
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(7), _doTare, CHANGE);
  attachInterrupt(digitalPinToInterrupt(5), _doCount, CHANGE);
  lcd.begin(16,2);
  pinMode(BackLight, OUTPUT);
  digitalWrite(BackLight, HIGH); 
  LCDLine1="Initializing ...";
  LCDLine2="";
  updateLCD();
  tareWeight=readingAverage(25,0);
}

void setLabel(char ch) {
  if(index < MaxChars && (isDigit(ch) or isAlpha(ch) or isWhitespace(ch))) {
    strValue[index++] = ch;
  }
  else
  {
    itemLabel=strValue;
    index = 0;
//    strValue[0]=(char)0;
    memset(strValue, 0, sizeof strValue);
    serialInputType=' ';
  }
}

void setItemWeight(char ch) {
  int tempWeight;
  if(index < MaxChars && isDigit(ch)) {
    strValue[index++] = ch;
  }
  else
  {
    tempWeight =atoi(strValue);
    if(tempWeight > 0){
      itemWeight=tempWeight/100.00;
      
   lcd.print(itemWeight);
    }
      index = 0;
      memset(strValue, 0, sizeof strValue);
      serialInputType=' ';
  }
}

void readCommand(char ch) {
  serialInputType=' ';
  switch (ch) {
    
    case '2' : // Count 25
      getItemWeight(25);
      break;

    case '5' : // Count 50
      getItemWeight(50);
      break;

    case '7' : // Count 75
      getItemWeight(75);
      break;

    case '1' : // Count 100
      getItemWeight(100);
      break;

    case 'T' : // Tare
      setTare();
      break;
  }
}

void serialEvent()
{
  while(Serial.available()) 
  {
    char ch = Serial.read();
    
    switch (serialInputType) {
      case 'W' : 
        setItemWeight(ch);
        break;
        
      case 'L' :
        setLabel(ch);
        break;
      
      case 'C' : 
        readCommand(ch);        
        break;      
      case 'V' : 
        Serial.println("Counting Scale - Version 0.9");
        break;
      case ' ' : 
        if (commandChars.indexOf(ch)>0) {
          serialInputType=ch;  
        }
        break;      
     }
   }
}
void loop() {
  if (doTare) { 
    setTare();
  }

  if (doCount) {
    getItemWeight(25);
  }
  
  average=readingAverage(25,tareWeight);
  Serial.println(average);
  LCDLine1=String(average*0.715)+"g";

  // if item weight has been set, calculate and show quantity
  if (itemWeight>0) {

    // Do not want to show quantity as negative
    if (average>0) {      
      LCDLine2=String(average / itemWeight,0);
    }
    else {
      LCDLine2="0";
    }

    // if there is an associated label, show it. Otherwise show pcs
    if (itemLabel!="") {
      LCDLine2=LCDLine2+" "+itemLabel;
    }
   else {
      LCDLine2=LCDLine2+" Pcs";
    }
  }
  updateLCD();
}

move the display away from the pin u want to use for an interrupt

What knut_ny indicates could easily have been prevented if you would have put all pin declarations together and used pin names instead of magic numbers. E.g.

...
...
HX711 scale(A4, A3);
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
const int BackLight = 8;

const int tarePin = 7;
const int countPin = 5;
...
...

You could (nearly) immediately see that pins 5 and 7 are used twice.

In setup

void setup()
{
  ...
  ...
  attachInterrupt(digitalPinToInterrupt(tarePin), _doTare, CHANGE);
  attachInterrupt(digitalPinToInterrupt(countPin), _doCount, CHANGE);
  ...
  ...
}

I take it one step further and would define pin names for all io pins and use those names also in the e.g. constructors.

E.g.

// digital pins
const byte pinLcdD7 = 2;
const byte pinLcdD6 = 3;
const byte pinLcdD5 = 4;
const byte pinLcdD4 = 5;
const byte pinLcdEna = 6;
const byte pinLcdRS = 7;
const byte pinLcdBack = 8;
const byte tarePin = 9;
const byte countPin = 10;
// analog pins (used both analog and digital)
const byte pinHX711_2 = A3;
const byte pinHX711_1 = A4;


LiquidCrystal lcd(pinLcdRS, pinLcdEna, pinLcdD4, pinLcdD5, pinLcdD6, pinLcdD7);
HX711 scale(pinHX711_1, pinHX711_2);

Note that I don't know what the HX711 pins are used for and hence generic names; change to whatever they actually do (clock and data?).
Also note that I define them in sequence; this makes it easier to find a free pin in the code. If I had the rs and enable lines connected to analog pins, they would have been in the analog 'section'.

Thank you very much for the help! It works now!!! :slight_smile: