I have the following code that works perfectly!! I know, thanks ;-}
int Header_Liquid_Level;
int *pointToHLL = &Header_Liquid_Level;
int Header_High_Pin = 2;
void setup() {
Serial.begin(9600);
pinMode(Header_High_Pin, INPUT);
int Header_Liquid_Level = digitalRead(Header_High_Pin);
attachInterrupt(digitalPinToInterrupt(Header_High_Pin), Level_ISR(Header_High_Pin, pointToHLL), CHANGE);
}
void loop() {
Serial.print("Header_Liquid_Level= ");
Serial.println(Header_Liquid_Level, DEC);
delay(500);
}
int Level_ISR(int Level_Pin, int *pointerToLevel) {
if (digitalRead(Level_Pin) == 0)
*pointerToLevel = 0;
else
*pointerToLevel = 1;
}
My question is why does Level_ISR need to have the return type defined as int when no value is returned? It won’t compile with the type set to void …
As a cheeky 2nd question, have I followed “good practice” with this code? Although it’s more complex than it needs to be for just one sensor, I will have 10 sensors in the final sketch.
Had me worried for a second there. I'm feeling better now
warning: invalid conversion from 'int' to 'void (*)()' [-fpermissive]
attachInterrupt(digitalPinToInterrupt(Header_High_Pin), Level_ISR(Header_High_Pin, pointToHLL), CHANGE);
So it will compile, but with clear warnings, which should indicate to the programmer that something isn't right. In this case the function prototype for the ISR is wrong.
have I followed “good practice” with this code?
Is this fundamentally a prohibited way to perform the task?
I'm not sure what the phrase "There are no input variables or returned values." means? Clearly, I have passed input variables to the ISR and it receives them and processes them correctly. Does that mean I have written an incorrect ISR?
I understand that there are no returned values, which is why I was wondering why void wasn't valid ...
As for "All changes have to be made on global variables." Does that mean that my use of pointers is also prohibited?
It's not that void isn't valid. It is! The problem is that an ISR prototype is "void ISR_Func(void)" and you are doing something completely different! If you restructure your ISR to be the way it should, it will compile just fine without any warnings. If you need to access external data in your ISR, then that's one of the few acceptable reasons to use global variables.
[edit]
I don't know the C/C++ compiler well enough to know why your code would work, but my guess is that the code generated is pushing those variables onto the stack and the ISR is somehow managing to retrieve them. Maybe. There's a lot of weird stuff that C does which works until it just doesn't. But that's not a reason to rely on unspecified behavior.
I can't deduce your actual intent from reading the code, but here is a possible solution which at least compiles without warnings and may be what you were trying to accomplish.
int Header_Liquid_Level;
int *pointToHLL = &Header_Liquid_Level;
int Header_High_Pin = 2;
int pointer_1 = 0;
int pointer_2 = 0;
int pointer_3 = 0;
int pointer_4 = 0;
int Liquid_Level_1 = 0;
int Liquid_Level_2 = 0;
int Liquid_Level_3 = 0;
int Liquid_Level_4 = 0;
struct ISR_MAP
{
int pin;
int levelPtr;
};
const int N_MAPS = 4;
volatile ISR_MAP pinMapping[N_MAPS] =
{
{Liquid_Level_1, pointer_1},
{Liquid_Level_2, pointer_2},
{Liquid_Level_3, pointer_3},
{Liquid_Level_4, pointer_4}
};
void Level_ISR()
{
for (int i = 0; i < N_MAPS; i++)
{
if (digitalRead(pinMapping[i].pin) == 0)
{
pinMapping[i].levelPtr = 0;
}
else
{
pinMapping[i].levelPtr = 1;
}
}
}
void setup() {
Serial.begin(9600);
pinMode(Header_High_Pin, INPUT);
int Header_Liquid_Level = digitalRead(Header_High_Pin);
attachInterrupt(digitalPinToInterrupt(Header_High_Pin), Level_ISR, CHANGE);
}
void loop() {
Serial.print("Header_Liquid_Level= ");
Serial.println(Header_Liquid_Level, DEC);
delay(500);
}
The set up I have is that I have 5 tanks of liquid. Each tank has a liquid sensor near the top and another near the bottom. Each sensor is connected to a different input pin on the Arduino. The task for the code is to detect any time, any of the sensors changes status (High -> Low) (Low -> High) and update the appropriate global variable. The further processing of that information is not relevant to this question.
With your code you are only responding to an interrupt on a single pin whereas I need to respond to 10. I completely understand that you couldn’t have known this.
What I have now come to understand is that the phrase “There are no input variables” means THOU SHALL NOT even think about passing any input variables to the ISR.
The really confusing thing is that the code works exactly as I had expected and the ISR uses the passed values correctly.
Where it gets even more confusing (for me) is that if I add code like this: