Replacing an encoder with a magnetic sensor ( I have the code)
so goal build program robot. have rotary encoder (or potentiometer) attached wheel , every time wheel spins, friction turns encoder , calculated distance me. but more accurate results, have since put magnet on wheel , taped sensor everytime magnet passes 1 revolution, magnetic sensor can record it.
have replaced potentiometer on wheel (controls steering) motor both motor , has encoder on top.
i have simple code lights led whenever magnet comes close. can guide me next?
have replaced potentiometer on wheel (controls steering) motor both motor , has encoder on top.
i have simple code lights led whenever magnet comes close. can guide me next?
code: [select]
circuit:
* potentiometer connected analog pin 0.
center pin of potentiometer goes analog pin.
side pins of potentiometer go +5v , ground
* "p" channel on motor driver connected digital pin 9
* "d" channel on motor driver connected digital pin 7
*/
// these constants won't change. they're used give names
// pins used:
const int analoginpin = a0; // analog input pin potentiometer attached to
const int analogoutpin = 9; // analog output pin "p" channel attached (pwm signal)
const int digitaloutpin = 7; // digital output pin "d" channel attached (controls motor direction)
const int pump = 10;
// pid gains
const int pgain = 3;
const int dgain = 1;
const int igain = 0.05;
// input , output variables
int sensorvalue = 0; // value read pot
int outputvalue = 0; // value output pwm (analog out)
// variables needed control law
double potangle = 0; // value in degrees
double prevpotangle = 0; // previous value read pot
double desiredposition = 185; // desired position (in degrees) want motor go to
double error = 0; // current error
double motorvelocity = 0; // first derivative of motorposition
double errorintegral = 0; // used in pid control law
double controlsignal = 0; // control signal sent motor
double interval = 50;
long previousmillis = 0;
// time keeping variables
int count = 0; // keeps track of time (for switching desired position)
int dt = 1; // time takes execute 1 loop (in ms)
int encoderpin1 = 2;
int encoderpin2 = 3;
int pumpstate = low;
volatile int lastencoded = 0;
volatile long encodervalue = 0;
////////////////////////stuff/to/chage/////////////////////////////////////////////
int steerangle = 217;
int distance = 330;
int brakeangle = 74;
///////////////////////////////////////////////////////////////////////////////
long lastencodervalue = 0;
int lastmsb = 0;
int lastlsb = 0;
unsigned long time;
void setup() {
// initialize serial communications @ 9600 bps:
serial.begin(9600); // allows write values serial monitor
pinmode(digitaloutpin, output); // sets "d" channel pin output
pinmode(pump, output);
pinmode(encoderpin1, input);
pinmode(encoderpin2, input);
digitalwrite(encoderpin1, high); //turn pullup resistor on
digitalwrite(encoderpin2, high); //turn pullup resistor on
//call updateencoder() when high/low changed seen
//on interrupt 0 (pin 2), or interrupt 1 (pin 3)
attachinterrupt(0, updateencoder, change);
attachinterrupt(1, updateencoder, change);
desiredposition = 90;
}
void loop() {
// read analog in value:
sensorvalue = analogread(analoginpin); // read integer b/w 0 , 1023 (10-bit resolution)
// first save previous value
prevpotangle = potangle;
// save new value, mapping value in degrees:
potangle = map(sensorvalue, 0, 1023, 0, 360);
// use compute error , motor speed
error = potangle - desiredposition;
motorvelocity = (potangle - prevpotangle)/(dt); // (in deg/ms)
errorintegral = errorintegral + error*(dt/1000);
// calculate motor control signal using pid control law
controlsignal = -1*pgain*error - dgain*motorvelocity - igain*errorintegral;
unsigned long currentmillis = millis();
// tell motor way spin
if (controlsignal >= 0) {
digitalwrite(digitaloutpin, high);
} else {
digitalwrite(digitaloutpin, low);
}
// map range of analog out:
controlsignal = abs(controlsignal); // can ouptut positive values
outputvalue = constrain(controlsignal, 0, 255); // 8-bit resolution
// change analog out value:
analogwrite(analogoutpin, outputvalue);
if(currentmillis - previousmillis > interval) {
// save last time blinked led
previousmillis = currentmillis;
// if led off turn on , vice-versa:
if (pumpstate == low)
pumpstate = high;
else
pumpstate = low;
// set led ledstate of variable:
digitalwrite(pump, pumpstate);
}
if (encodervalue>=distance)
{
pumpstate=low;
}
if (currentmillis>=57000)
{
pumpstate=high;
}
// print results serial monitor: (uncomment display)
// serial.print("desired position = " );
// serial.print(desiredposition);
// serial.print("\t actual position = ");
// serial.print(potangle);
// serial.print("\t rotarty = ");
// serial.println(encodervalue);
if (encodervalue >=distance) {
desiredposition = brakeangle;}
else {
desiredposition = steerangle;
}
}
void updateencoder(){
int msb = digitalread(encoderpin1); //msb = significant bit
int lsb = digitalread(encoderpin2); //lsb = least significant bit
int encoded = (msb << 1) |lsb; //converting 2 pin value single number
int sum = (lastencoded << 2) | encoded; //adding previous encoded value
if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) encodervalue ++;
if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encodervalue --;
lastencoded = encoded; //store value next time
}
you want control movement. ?
..and replace n pulses/rev 1 pulse/rev ??
this diffucult understand!
.......................
to 'full control' - lego .. use stepper motors
..and replace n pulses/rev 1 pulse/rev ??
this diffucult understand!
.......................
to 'full control' - lego .. use stepper motors
Arduino Forum > Using Arduino > Sensors > Replacing an encoder with a magnetic sensor ( I have the code)
arduino
Comments
Post a Comment