Hi!
I would like to implement 2 buttons as limiting
switches for an motor controlled axis. I check which
button is pressed by measuring the resistance of
each button (resitors before the buttons; the approach
works normally fine).
The thing is that the stepper motors seem to get
really slowed down when measuring the analog value
of the buttons all the time. If I comment the analogRead
out the steppers run fine otherwise they get really slow
and making a lot of noise and vibration.
So the question is:
Slows analogRead() the processor that hard? Are there
ways to compensate this behaviour?
In the class:
void AxisCtrl::home()
{
motorOverride(1);
if(limitSwitchState() == 1)
{
_axisHomed = true;
_currStepPos = 0;
}
}
void AxisCtrl::motorOverride(int dir)
{
unsigned long currentMicros = micros();
if(currentMicros - _previousCycle > _motorSpeed) {
_previousCycle = currentMicros;
if(_motorPinState == 0){
_motorPinState = 1;
} else {
_motorPinState = 0;
}
digitalWrite(_dirPin, dir);
digitalWrite(_motorPin,_motorPinState);
}
}
int AxisCtrl::limitSwitchState()
{
int btnNr;
int btnVal = analogRead(_limitSwitchesPin);
if(btnVal > 1000){
btnNr = 0;
} else if(btnVal>_axisHomeBtnVal-10 && btnVal<_axisHomeBtnVal+10){
btnNr = 1;
} else if(btnVal>_axisStopBtnVal-10 && btnVal<_axisStopBtnVal+10){
btnNr = 2;
}
return btnNr;
}
In the loop():
if(homeAll){
x.home();
y.home();
z.home();
}
Thanks in advance!
Regards!
Marius
You can do analogRead asynchronously, as I show here:
Scroll down to: "Read the Analog-to-Digital converter asynchronously"
That way the analog read is happening in the background.
Otherwise each analogRead takes 104 uS which will probably make a noticeable impact.
Thanks Nick!
I tried the ISR function but I cant get it work. 
This is my code (please note that I deleted for readability
all functions and variables that are not important here):
In the loop:
void loop() {
Serial.println(x.limitSwitchState());
}
Class h.:
#ifndef AxisCtrl_h
#define AxisCtrl_h
#include "Arduino.h"
class AxisCtrl
{
public:
AxisCtrl(int motorPin, int dirPin, int limitSwitchesPin,int steps, float leadPitch);
int limitSwitchState();
void home();
private:
volatile int adcReading;
volatile boolean adcDone;
boolean adcStarted;
};
#endif
And my cpp:
AxisCtrl::AxisCtrl(int motorPin, int dirPin, int limitSwitchesPin, int steps, float leadPitch)
{
ADMUX = _BV (REFS0) | (limitSwitchesPin & 0x07);
}
int AxisCtrl::limitSwitchState()
{
int btnNr;
// if last reading finished, process it
if (adcDone)
{
adcStarted = false;
if(adcReading>_axisHomeBtnVal-10 && adcReading<_axisHomeBtnVal+10){
btnNr = 1;
} else if(adcReading>_axisStopBtnVal-10 && adcReading<_axisStopBtnVal+10){
btnNr = 2;
}
return btnNr;
adcDone = false;
}
// if we aren't taking a reading, start a new one
if (!adcStarted)
{
adcStarted = true;
// start the conversion
ADCSRA |= _BV (ADSC) | _BV (ADIE);
}
// do other stuff here
}
ISR (ADC_vect)
{
byte low, high;
// we have to read ADCL first; doing so locks both ADCL
// and ADCH until ADCH is read. reading ADCL second would
// cause the results of each conversion to be discarded,
// as ADCL and ADCH would be locked when it completed.
low = ADCL;
high = ADCH;
adcReading = (high << 8) | low;
adcDone = true;
} // end of ADC_vect
I allways get a
C:\_Marius\EigeneProjekte\prj0009_CNCMaschine\prj0009_CNCMaschine\Binary_Arduino\libraries\AxisCtrl\AxisCtrl.cpp: In function 'void __vector_21()':
C:\_Marius\EigeneProjekte\prj0009_CNCMaschine\prj0009_CNCMaschine\Binary_Arduino\libraries\AxisCtrl\AxisCtrl.cpp:262: error: 'adcReading' was not declared in this scope
C:\_Marius\EigeneProjekte\prj0009_CNCMaschine\prj0009_CNCMaschine\Binary_Arduino\libraries\AxisCtrl\AxisCtrl.cpp:263: error: 'adcDone' was not declared in this scope
If I define the 2 variables inside the ISR function again it compiles but
I get nonsense readings.
Is it even possible to use the ISR inside a class?
Thanks!
ISRs cannot access class variables like that. Which instance of the class do they refer to?
Hm. Im not really sure what you mean by:
Which instance of the class do they refer to?
They get instanciated in the "AxisCtrl" class.
But to be honest I think I will just use 6 pins for each axis and
dont save 3 pins by using analog readings. DigitalRead() seams
to be a lot faster! 
But thanks again Nick, I will investigate this behaviour later. 
asuryan:
Hm. Im not really sure what you mean by:
Which instance of the class do they refer to?
They get instanciated in the "AxisCtrl" class.
There is a difference between a class and an instance. For example a dog is a class of animal, and Fido is an instance of the class dog.
In your code you have:
ISR (ADC_vect)
{
...
adcReading = (high << 8) | low;
adcDone = true;
} // end of ADC_vect
And your class has those variables:
class AxisCtrl
{
...
private:
volatile int adcReading;
volatile boolean adcDone;
boolean adcStarted;
};
But the variables exist in an instance of the class. eg.
AxisCtrl control1;
AxisCtrl control2;
AxisCtrl control3;
So the ISR has no way of knowing which instance of the class you are referring to in the ISR.