|
|
|
![]() |
|
|||||||
|
||||||||
![]() |
|
|
Thread Tools | Rate Thread | Display Modes |
|
|
|
#1
|
|||
|
|||
|
Arduino and kop encoder
Has any one used the encoder included in the KOP with the arduino? can someone give me the code for it so i can read the rpm?
Thanks |
|
#2
|
||||
|
||||
|
Re: Arduino and kop encoder
Quote:
Let me push you in the right direction and see how far you can go. Don't be surprised if you learn to fly along the way. The first thing you want to learn is how to use the "interrupt" input(s), more specifically, "External Interrupt". One channel of the encoder will go to that input. The other channel will be used to determine direction. Your interrupt service routine will sample that input. High would be forward, otherwise it's reverse. RPM after that is simply a little math. OK, that's enough hints for now. Let us know what you find. I'll always help you out if you just ask. Last edited by billbo911 : 04-25-2012 at 09:45 AM. |
|
#3
|
||||
|
||||
|
Re: Arduino and kop encoder
We are using a Grayhill 63R64 encoder with an Arduino mega for the RPMs of our shooter. We opted for that encoder instead of the KOP because the PPR on the KOP encoder is so high that we were concerned at overrunning the Arduino. Further testing shows that the Arduino is easily capable of 30,000 PPS. So, that concern turned out to be bogus. But, using the KOP encoder would require another gearbox up high on our bot that would adversely effect the COG while trying to balance or going over the bump.
The Arduino mega can source the 5V for the Grayhill or the KOP encoder with no problem. We bring the A channel back from the encoder to Digital Pin 2 on the Arduino. The magic you're looking for can be found in the "attachInterrupt" command. Use it to increment a counter on the rising edge of the encoder pulse and then periodically read the pulse count and do your math for the RPM. We also added the "SimpleTimer" library from the Arduino playground site so we could get updates every 100 ms. This library attaches a timer interrupt to a function so it's called at the interval you desire rather than simply polling the counter. Our code sends it's output via an Ethernet shield direct to the cRio using UDP. We found some really interesting gotchas with the cRio robot code in that you must read the packets or face the possibility of a robot lockup. So, you'll need a blocking thread to read the socket constantly. Our robot code is written in C++, so creating a thread was pretty easy. In addition, our Arduino is also sampling an absolute encoder on our ball shooting angle device. No problem doing both functions and sending out the results. I'd say that the entire Arduino program for both sensors and the Ethernet output is maybe 50 lines of code total. |
|
#4
|
|||
|
|||
|
Re: Arduino and kop encoder
how do i use the simpletimer and the attachinterrupt command?
|
|
#5
|
||||
|
||||
|
Re: Arduino and kop encoder
Too funny. I'm literally doing this as I speak. Here's my code.
Code:
// Controlling a servo position using a potentiometer (variable resistor)
// by Michal Rinott <http://people.interaction-ivrea.it/m.rinott>
#include <Servo.h>
Servo motor1; // create servo object to control a motor
Servo motor2; // ditto
int potpin = 0; // analog pin used to connect the potentiometer
int val; // variable to read the value from the analog pin
volatile byte rpmcount;
unsigned int rpm;
unsigned long timeold;
void setup()
{
motor1.attach(9); // attaches the motor 1 on pin 9 to the servo object
motor2.attach(10); // attaches the motor 2 on pin 10 to the servo object
attachInterrupt(0, rpm_fun, RISING); // attaches the encoder on (digital pin 2)
rpmcount = 0;
rpm = 0;
timeold = 0;
digitalWrite(2, HIGH);
Serial.begin(9600);
}
void loop()
{
val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023)
val = map(val, 0, 1023, 0, 179); // scale it to use it with the servo (value between 0 and 180)
if (rpmcount >= 0) {
rpm = 30*1000/(millis() - timeold)*rpmcount;
timeold = millis();
rpmcount = 0;
Serial.print("RPM: ");
Serial.print(rpm);
Serial.print(" Pot: ");
Serial.print(val);
Serial.print("\n");
}
motor1.write(val); // sets the motor speed according to the scaled value
motor2.write(val);
}
void rpm_fun()
{
rpmcount++;
}
Last edited by Michael Hill : 04-25-2012 at 06:51 PM. |
|
#6
|
||||
|
||||
|
Re: Arduino and kop encoder
You have to treat victors as servos rather than directly feed PWM. Victors actually read PPM, so you have to treat them as servos (which read PPM) in Arduino.
|
|
#7
|
|||
|
|||
|
Re: Arduino and kop encoder
do i have to divide the rpm by 360 since my encoder has 360 positions in 1 rotation?
|
|
#8
|
|||
|
|||
|
Re: Arduino and kop encoder
i noticed that your code resets back to zero after 60,000 rpm. it is reading much faster that actually spinning. what do i do to make it the actual rpm
My encoder is the kop encoder and it has 360 positions in 1 rotation |
|
#9
|
||||
|
||||
|
Re: Arduino and kop encoder
Quote:
Code:
// Controlling a servo position using a potentiometer (variable resistor)
// by Michal Rinott <http://people.interaction-ivrea.it/m.rinott>
#include <Servo.h>
Servo motor1; // create servo object to control a motor
Servo motor2; // ditto
int potpin = 0; // analog pin used to connect the potentiometer
int val; // variable to read the value from the analog pin
float dt;
volatile byte rpmcount;
float rpm;
unsigned long timeold;
void setup()
{
motor1.attach(9); // attaches motor 1 on pin 9 to the servo object
motor2.attach(10); // ditto
attachInterrupt(0, rpm_fun, RISING);
rpmcount = 0;
rpm = 0;
timeold = 0;
digitalWrite(2, HIGH);
Serial.begin(9600);
}
void loop()
{
val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023)
val = map(val, 0, 1023, 0, 179); // scale it to use it with the motor (value between 0 and 180)
if (rpmcount >= 20) {
dt = (float)(millis() - timeold)/1000;
Serial.print(dt);
rpm = rpmcount/dt*60;
timeold = millis();
rpmcount = 0;
Serial.print(" RPM: ");
Serial.print(rpm);
Serial.print(" Pot: ");
Serial.print(val);
Serial.print("\n");
}
motor1.write(val); // sets the motor speed according to the scaled value
motor2.write(val);
}
void rpm_fun()
{
rpmcount++;
}
|
|
#10
|
|||
|
|||
|
Re: Arduino and kop encoder
Quote:
with your new code, the faster it spins, the lower the rpm. Last edited by SeanPerez : 04-25-2012 at 08:06 PM. |
|
#11
|
||||
|
||||
|
Re: Arduino and kop encoder
Quote:
If you are, disregard that. That's the "dt" value. Sorry, I didn't make it very legible. Look at the second set of numbers. 0.43 RPM: 2803.74 Pot: 82 means that 0.43 is the time between calculations, 2803.74 is the revolutions per minute, and 82 is the potentiometer value. |
|
#12
|
|||
|
|||
|
Re: Arduino and kop encoder
ok now im reading the right number. but it seems the rpm is way to high then the actual rpm.
im spinning it by hand and its reading around 21,000 rpm. this is way to high. im spinning it at around 60 rpm +or- 10 rpm |
|
#13
|
|||
|
|||
|
Re: Arduino and kop encoder
Quote:
|
|
#14
|
||||
|
||||
|
Re: Arduino and kop encoder
Quote:
HTH, Mike |
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|