Hello,
I want to set my stepper motor by using the "attachInterrupt" function but it doesn´t work and I cant´t find my fault.
It would be nice if someone could help me with my code.
Hello,
I want to set my stepper motor by using the "attachInterrupt" function but it doesn´t work and I cant´t find my fault.
It would be nice if someone could help me with my code.
This is wrong:-
attachInterrupt(Taster1, mul, RISING); //Pin 2 als Interrupt-Pin = Int.2
attachInterrupt(Taster2, edul, RISING); //Pin 3 als Interrupt-Pin = Int.3
attachInterrupt(Taster3, stopp, RISING); //Pin 19 als Interrupt-Pin = Int.4
The first parameter specifies the interrupt mode not the interrupt pin unless you are on a Due. Which as you haven't said so I don't know.
There is also a lot of other stuff you are keeping secret like what triggers the interrupt.
if(i=0)
I think you men == not =
That goes for all your if statements.
Thanks much for your reply and help!!!
I produced much more problems by trying to correct my code myself(like the = in if-statements)
I use a Arduino Mega 2560 and my interrupt ports are triggered by simple push buttons with 5V.
My stepper is a bipolar version with wires "gruen" and "schwarz" for inductor 1, "blau" and "rot" are for inductor 2.
At the beginning the motor should be in "stopp-Mode" and then act, if a push button is activated.
I have attached the corrected sketch, but I think there aremore faults I can´t find, because the stepper isn´t doing what I want.
I hope this information is enough to understand what I meant.
my interrupt ports are triggered by simple push buttons with 5V.
And a pull down resistor?
I can't understand why you have a 1 second delay in the loop. In fact it is difficult to see what you are trying to do in the code. It is very unconventional, can you talk through what you are trying to do and how you hope to achieve it.
Why are you using i for the variable that the ISR sets and also the loop uses. It is two different values you know with the use of
for( int i = 127; i >= 0 ; i-- )
this value is NOT changed by the ISR.
Please read the how to use the forum sticky and post your code using the code tabs, it is much easier to see.
It is very inappropriate to use interrupts for pushbuttons - or for that matter, steppers - as these are very slow operations and interrupts are for servicing fast events (in the order of microseconds).
It is possible, but requires much more skill and as it is completely unnecessary, should simply be avoided.
You need to study techniques such as debouncing and completely avoiding the use of the "delay()" function.
Pushbuttons should be wired to ground and use the internal pull-up function in the ATmega chip.
I try to explain the features of my code:
Firstly, I declared the input pins for my stepper motor
// outputs to supply the inductors (inductor1= grün and schwarz, inductor2=blau and rot)
int Anschluss_gruen = 8; //int cable colour, pin
int Anschluss_schwarz = 9;
int Anschluss_blau = 12;
int Anschluss_rot = 13;
After the array for my sine wave values(they should be correct, tested without buttons) I declared a variable n which is used to run the right loop in "void loop":
//variable for while loop (at the beginning=200 to start with "void stopp" -> stepper doesn´t move )
volatile int n=200;
I use 3 buttons for my operations mul,edul and stopp, furthermore a potentiometer to change the delay to change speed. These are supported by 5V:
analogWrite(7, 255); //voltage=5V at pin7 to supply buttons and potentiometer with 5V
Next I´m activating the pulldown at my interrupt pins and define the attachInterrupt:
//input declaration of Push-Button input pins
pinMode(2, INPUT);
pinMode(18, INPUT);
pinMode(21, INPUT);
// turn on pulldown resistors
digitalWrite(2, LOW);
digitalWrite(18, LOW);
digitalWrite(3, LOW);
interrupts();
attachInterrupt(0, mul, RISING); // interrupt 0 is digital pin 2
attachInterrupt(5, edul, RISING); // interrupt 5 is digital pin 18
attachInterrupt(1, stopp, RISING); // interrupt 1 is digital pin 3
My idea was to use the attachInterrupt to activate another function(void mul(), void edul() or void stopp()), which is changing my variable n, for example mul():
void mul()
{
n=0;
}
Now the value n=0 is used to run through void loop, but only use the (while==n) loop.
while(n==0)
{
int i=0;
for(int i=0; i<127; i++)
{
analogWrite(Anschluss_gruen, gruen[i]);
analogWrite(Anschluss_schwarz, schwarz[i]);
analogWrite(Anschluss_blau, blau[i]);
analogWrite(Anschluss_rot, rot[i]);
delayMicroseconds((analogRead(A7))*10); //reads Analog input of potentiometer, to change delay(->change speed)
if(n!=0)
{
break;
}
}
}
This should be done as long as I´m not pushing another button. When I´m pushing another button, his interrupt-function should interrupt the n==0 loop and because of the changed n run the other loop (for example while(n==127)).
I´ve attached the whole code again.
Sometimes my code seems to work, but sometimes again not. Is this because of the bouncing behavior of the push buttons (I don´t understand how to debounce) or did I make another fault?
Thanks
I suggest you start again from scratch and don't even think about interrupts.
Why are you using analogWrite() in various places when digitalWrite() would seem to be the proper command? - for example to set a pin to 5v and to send pulses to the motor?
You seem to be setting all 4 wires to the motor HIGH at the same time - that makes no sense.
Don't use "while (n==0)" to duplicate what loop() is already doing.
The normal speed of the program running through loop() will be more than adequate for checking whether buttons are pressed.
You need to study the "blink without delay" example so you can use that concept and also study the concept of State Machines.
...R
Where you are going wrong is to change the variable i with the interrupts.
What you need to do is to change values that affect the stepping sequence itself.
I don't know why you are using such a long look up table it needs to be only 4 or 8 steps long.
Then when you increment the index make it wrap round so it always stays within limits.
When you move the index do it with
i = i + dir;
Where dir is a byte variable which your interrupt changes between 1 and -1 depending on the interrupt. Make this a byte because using an int will be very messy because it is possible one byte will change in between the increment operation.
Make your stop interrupt change dir to zero. Then a direction interrupt will set it going again.
This is getting to be my "hobby horse", but interrupts are a nasty distraction to "newbie" programmers. Interrupts can be - and should almost always be - completely ignored and left to the ambit of certain library routines such as those for keeping time.
In this case, you have been confused by the idea that an interrupt will "interrupt" what you are presently doing. In fact and to the contrary, it is a critical point of design that your program as such should never know that an interrupt has occurred at all because the interrupt has left the operating state of the main routine absolutely unchanged. Interrupts are intended only for events that occur in "computer time"; that need to be attended to within microseconds. By the same token, they have to be dealt with and completed within fractions of a millisecond - if only because other such important events may require attention.
{Quoting myself in one or more previous posts. :D}
Paul__B:
This is getting to be my "hobby horse", but interrupts are a nasty distraction to "newbie" programmers. Interrupts can be - and should almost always be - completely ignored and left to the ambit of certain library routines such as those for keeping time.In this case, you have been confused by the idea that an interrupt will "interrupt" what you are presently doing. In fact and to the contrary, it is a critical point of design that your program as such should never know that an interrupt has occurred at all because the interrupt has left the operating state of the main routine absolutely unchanged. Interrupts are intended only for events that occur in "computer time"; that need to be attended to within microseconds. By the same token, they have to be dealt with and completed within fractions of a millisecond - if only because other such important events may require attention.
{Quoting myself in one or more previous posts. :D}
OK I will get on my hobby horse, this post is very much misguided and where it is not it is wrong.
The whole point of an interrupt is that it interrupts the normal program flow to do something. It may or may not alter the eventual program flow in the main program but most of the times it does.
Yes interrupts in general should be short but they don't have to be, it depends on the application.
There is nothing wrong with what the OP is trying to do.
You tend to make generalizations as if you had been taught by some narrow minded person. With this attitude you totally limit what a micro computer system can do.
The mistake beginners actually make is thinking that an interrupt can redirect the program flow of the interrupted program. While in machine code it actually could, by altering the return address on the stack, there is no mechanism in C to do this, as far as I know. The best way of interacting between a program and an ISR is by setting flags / altering variables.
Most of the uses of interrupts will interact with the main code flow.
I will agree that beginners often use interrupts where there is no need but this should not preclude teaching them about where they are useful.
Some code can be totally interrupt driven and once in an ISR that in itself can be interrupted if you design it that way. That is why there are interrupt priority encoders and hardware built into many micro processors.
Niete:
Thanks much for your reply and help!!!
I produced much more problems by trying to correct my code myself(like the = in if-statements)
Understanding the use of "=" & "==" are fundamental concepts that you really need to get right in your head before trying to program much of anything in my mind.
I use a Arduino Mega 2560 and my interrupt ports are triggered by simple push buttons with 5V.
My stepper is a bipolar version with wires "gruen" and "schwarz" for inductor 1, "blau" and "rot" are for inductor 2.
At the beginning the motor should be in "stopp-Mode" and then act, if a push button is activated.I have attached the corrected sketch, but I think there aremore faults I can´t find, because the stepper isn´t doing what I want.
I hope this information is enough to understand what I meant.
I don´t understand exactly the way you would change the code. Could you explain it again where to use the
i = i+dir
i = i+dir
Use it when you want to increment the index of your stepping motor coil pattern look up table.
Note that you will have to make it wrap round as well. That is when it is greater than the maximum set it to the minimum and lower than the minimum set it to the maximum.
You need to remove both your for loops.
I have changed my loop this way:
void loop()
{
if (i=128)
{i=0;}
if (i=-1)
{i=127;}
analogWrite(Anschluss_gruen, gruen[i]);
analogWrite(Anschluss_schwarz, schwarz[i]);
analogWrite(Anschluss_blau, blau[i]);
analogWrite(Anschluss_rot, rot[i]);
delayMicroseconds(2000);
i=i+dir;
}
My attachInterrupt changes the dir variable from 1 to -1, 0 or bach to 1.
If my index i is higher than 127, its written back to 0, and if it ran under 0, its written to 127.
Is this the way you suggested? I´m not able to run the stepper again and have no idea what to do else
Yes that is the sort of thing although you have the code wrong in the if statements. It is == not =
Also it is better to put > 127 rather than == 128 and also < 0
Post the whole code if you still can't get it working.
I´m still not able to run the code successfully.
The variable dir must be volatile and the definition in the setup function does nothing, remove it.
I´m sorry, but I still have problems
So use print statements to see your variables and find out where it is going wrong.
OK,thanks for your effort and help. I´ll use to do it