Specific problem in calling subroutines. Help needed.

Hello everyone. It's my first post on the forum so please pardon me if something here is not in correct order or how it should be.

WHAT I AM TRYING TO DO:-

Ok so i am making a project in which i am rotating a turntable via motor.
There are 4 sensors each placed at 90 degrees to stop the turntable according to the button i have pressed.
A valve assembly is up there which opens only for that particular sensor or for that position after sensor stops motor at that position.

PROBLEM THAT I AM FACING:-

I learned about using subroutines from the forum and i've attached the code i wrote. The problem i am facing is that even after calling my subroutine in the void loop it's not working (Motor keeps running). I am using proper syntax and all. The most surprising thing is that when i drop IF statement from my subroutine it starts working.
Everything remains same and all i remove is IF statement for it to work but i need IF statement cause without it there is no meaning of my subroutine.

Please help me out. Other than this my circuitry is all perfect and there is no problem with anything except the program i am writing.

int bcoke = 2; /*Button input that runs my motor*/
int mp1 = 6; /*Motor Supply*/
int vcoke = 7; /*Output for Base input of my valve circuitry*/
int ircoke = 11; /* IR Sensor placed at 90 degrees to stop motor there*/
int irstop = 10; /*Final IR sensor to stop at 360 degrees*/
int co;
int de;
int irc;
int irs;

void setup()
{
  pinMode (bcoke, INPUT);
  pinMode (mp1, OUTPUT);
  pinMode (vcoke, OUTPUT);
  pinMode (irstop, INPUT);
  pinMode (ircoke, INPUT);
}


void loop()
{
  co = digitalRead(bcoke);
  irs = digitalRead(irstop);
  irc = digitalRead(ircoke);
  
  if(co == LOW)
  {
   digitalWrite(mp1, HIGH);
   coke();
  }
}


void coke()
{
  if (irc == LOW)
  {
    digitalWrite(mp1, LOW);
    digitalWrite(vcoke, HIGH);
    delay(5000);
    digitalWrite(vcoke, LOW);
    delay(1000);
    digitalWrite(mp1, HIGH);
  }
}

It helps immensely to see a schematic.

You do know using delay(x) pauses all program execution for that amount of time.

Delta_G:
I'm a bit confused. I take it the mp1 pin is the pin that controls the motor right? Is the motor on when the pin is HIGH or when it is LOW?

Either way, it looks like the function you call just puts mp1 back to the same state it was before the function got called. Does any of the other stuff in the function happen? Does the vcoke pin go HIGH and LOW?

Hi. Thanks for reply.
Yes Motor is ON when the pin goes HIGH & stops when Pin goes LOW.

No nothing else happened. Motor just keeps on Running and Running. To see if my function was working properly i did these changes in my program...

irc = digitalRead(ircoke);
 
  if(co == LOW)
  {
   digitalWrite(mp1, HIGH);
   delay (2000);
   coke();
  }
}


void coke()
{
    digitalWrite(mp1, LOW);
    digitalWrite(vcoke, HIGH);
    delay(5000);
    digitalWrite(vcoke, LOW);
    delay(1000);
    digitalWrite(mp1, HIGH);
  }
}

And now it was working all fine. As soon as motor stops all other statements start running.
I can see sensor blinking and sensing but somehow my program isn't getting into that IF statement block and telling motor to stop. What do i do now? Please help.

LarryD:
It helps immensely to see a schematic.

You do know using delay(x) pauses all program execution for that amount of time.

Yes i know it pauses the program right there and that's what i want. After my motor stops i want a delay for my valve to pour water in the glass and then after valve closes the motor starts running again which is finally stop by the sensor at the start position that is after on full rotation by the turntable.

How are pins 2,11,10 wired?

Delta_G:
That last bit is the confusing bit. In the code, I see where it reads your button and goes to the subroutine. The subroutine stops the motor and operates the valve for a bit and then starts the motor again. But after that, there is no code anywhere to stop the motor again. The only code I see in loop is checking the state of the button and calling that one subroutine.

Are you showing ALL of the code?

Yes you got what i am trying to do with the code i wrote, but still the problem is that it doesn't stop the motor and then operate the valve. I mean it looks like as if SUBROUTINE isn't working as long as i am using that IF condition where it reads my IR sensor. It's like the sensor is useless and so is SUBROUTINE. Motor keeps on running and running. I mean logically is should've gone into the SUBROUTINE and read

if(irc == LOW)
{
stop motor
open valve
delay for 5sec
close valve
start again
}

but it seems like it just doesn't read the very 1st if (irc == LOW) condition.

And no it's just the subroutine for 1 sensor i have shown here. There is another sensor located at the initial (360 deg) position which when read by Arduino stops the motor permanently.
There are other two sensors i need to add at 180 deg and 270 deg to basically stop my turntable at 4 diff locations each separated by 90 degrees.

I thought if this Subroutine thing worked then i would just make 3 subroutines Coke();, Pepsi(); & Fanta(); and a Stopp(); subroutine to stop the motor at initial position.

LarryD:
How are pins 2,11,10 wired?

Sorry but i didn't get you. I mean they are wired directly to the device. For ex- Buttonpin is there to give INPUT to Arduino and it's directly connected to the Pin 2. I am using an internal pullup resistor which when pressed goes LOW.
Sensor OUTPUT is connected to the Pin 11 & 10. There are 2 IR sensors i am using here.

Delta_G:
Are you sure that irc will already be LOW when the subroutine enters? If it isn't already low when the button is pressed and the subroutine starts, then that if condition is false and everything in your subroutine gets skipped. You don't read the sensor in the subroutine, so it would actually have to be already reading LOW at the same time the button was read.

No well my irc is actually high when the button is pressed in fact it remains high all the time. The only time it goes low is when a black color mark (i made on turntable) passes thru that IR sensor. That's when the IR output goes low which i want Arduino to read and then stop the motor according to it.

Am i doing it wrong here?? Please help me out. How should i code it??

Delta_G:
Are you sure that irc will already be LOW when the subroutine enters? If it isn't already low when the button is pressed and the subroutine starts, then that if condition is false and everything in your subroutine gets skipped. You don't read the sensor in the subroutine, so it would actually have to be already reading LOW at the same time the button was read.

Do you want me to put irc= digitalRead(ircoke); into the coke(); subroutine?? I guess i tried it but had no success. I will try it out again if you ask me to but is it what you are actually trying to tell me??

Delta_G:
A better solution would be to implement a state machine. You'd have three states right now, nothing happening, button pushed waiting for sensor to go LOW, and running the coke function.

int state = 0;   // global scope or static variable

void loop(){

if(state is 0 and button is pushed) state = 1;

if(state is 1 and sensor is LOW) state = 2;

if(state is 2) run coke function and set state back to 0.
}

Hi. Thanks for the 1st solution you posted i am gonna go & try that out first.
And well i am not that familiar with state machine. Where can i find a tutorial or reference material or something? Sorry but i am new to this Arduino thing and i am just in the learning phase. Will bump this post shortly and keep you updated.
Thanks again.

Thanks for the link. I will go search others out if needed.
And well the 1st solution didn't work. I copied the modification you made and the motor still isn't stopping.

int bcoke = 2;

int mp1 = 6;
int vcoke = 7;
int irstop = 10;
int ircoke = 11;
int co;
int irc;
int irs;

void setup()
{
  pinMode (bcoke, INPUT);
  pinMode (mp1, OUTPUT);
  pinMode (vcoke, OUTPUT);
  pinMode (irstop, INPUT);
  pinMode (ircoke, INPUT);
}

void loop()
{
  co = digitalRead(bcoke);
  irs = digitalRead(irstop);
  irc = digitalRead(ircoke);
    
  if(co == LOW)
  {
    digitalWrite(mp1,HIGH);
  }else
  {
    if (irc == LOW)
  {
    digitalWrite(mp1, LOW);
    digitalWrite(vcoke, HIGH);
    delay(5000);
    digitalWrite(vcoke, LOW);
    delay(1000);
    digitalWrite(mp1, HIGH);
  }else
  {
    if (irs == LOW)
    {
      digitalWrite(mp1, LOW);
    }
  }
  }
}

Well give this code a look as well. It was working perfectly. bcoke when pressed was running motor and when ircoke was going LOW, motor was stopping and valve was working fine as well.

The major problem here was that when i used 1 more button, 1 more sensor and 1 more valve for another drink everything got mixed up.

For ex- I pressed bpepsi and wanted only irpepsi to stop the motor. But what really happened is that once the motor went HIGH arduino was unable to differentiate between which button caused motor to go HIGH and therefore 1st ircoke and vcoke were being activated and then when turntable reached irpepsi and vpepsi they were activated.

I just can't find the solution here. Please help if you are getting my point.

Please help me out with the coding. Final dates for the project have been announced and now i am not in any state to start all over again.
If you aren't busy can you please help with State Machine thing??

Thanks again for this piece of code. And you kind of guess all the numbers right. Haha

Btw i just copied the code and was trying to compile when this error popped up. I guess it's something related to scope of state we declared. I have attached a snapshot.

Regards,

Delta_G:
Yeah, you caught it between my two edits. It's fixed now. I just compiled it on my computer and it went fine.

Yeah i just compiled and since everything looked fine i removed my post. Sorry. Haha

Well i am gonna go now and upload and run it on my setup. Will keep you updated about how it went. Thanks for helping out bro.

Damn. I must tell you how grateful i am for this help of yours.
Thanks a ton Delta_G bro.

That state machine thing you helped me with i must tell you how awesome it is.
And i actually got it once i started running it. I am just changing or you can say transferring my motor's control according to the buttons i press & sensors I WANT to sense. And it's too simple to go with. Hell i can't even imagine how tough or impossible it seemed for me to do it with IF ELSE and WHILE loops.

Not only i am able to simply pour three drinks with the help of STATE MACHINE (Which was looking too difficult just by IF ELSE's) in fact i have now created another two States in which i am able to serve two MIXED drinks as well. So in total i can serve 5 drinks just from 3 pouring platforms which i wouldn't have even imagined without using STATE MACHINE.

And the thing which blows my mind away is that how simple it makes my program.

MUST THANK YOU BRO. You are an awesome guy. Love ya. No Homo
Came on this forum expecting a little help and had a great experience. This forum is AWESOME. :sob: :smiley: :smiley: