Offline
Newbie
Karma: 0
Posts: 6
|
 |
« on: January 09, 2013, 10:05:52 pm » |
Hi guys, I just bought this encoder http://usdigital.com/assets/datasheets/E7P_datasheet.pdf?k=634861190727125957and I'm trying to use it in my robot by using this code: // Define pin locations and delay time between each query #define EncoderPinA 3 #define EncoderPinB 5 #define DELAY_TIME 500 // Define some physical constants #define WHEEL_CIRCUMFERENCE 0.9 // In meters #define WHEEL_TICKS 244 // The number of 'ticks' for a full wheel cycle // Create a variable in memory that the interrupt code can access // Also create the change value globally volatile unsigned int EncoderPos = 0; double dVal = 0; // Initialize void setup() { // Set input pin state for the line sensors pinMode(EncoderPinA, INPUT); pinMode(EncoderPinB, INPUT); // Register a hardware interupt function for pin 3 (which is indexed by value 1) // This function sets the EncoderEvent() function to be called whenever a line detector detects a change attachInterrupt(1, EncoderEvent, CHANGE); // Start serial communication Serial.begin (9600); } // Program loop void loop() { // Find the before and after value between the delay times unsigned int OldPos = EncoderPos; delay(DELAY_TIME); unsigned int NewPos = EncoderPos; // If an integer overflow occures, throw out the new value if(abs(NewPos - OldPos) < 30000) dVal = ((double)(NewPos - OldPos) / (double)DELAY_TIME) * 1000.0; // Convert between angular velocity to velocity double angVel = dVal / (double)WHEEL_TICKS; double velocity = (angVel * WHEEL_CIRCUMFERENCE); // Print data Serial.print("Velocity: "); PrintDouble(velocity, 5); } // Encoder event for the interrupt call void EncoderEvent() { // Read for data and bit changes // This is gray-code logic if (digitalRead(EncoderPinA) == HIGH) { if (digitalRead(EncoderPinB) == LOW) EncoderPos++; else EncoderPos--; } else { if (digitalRead(EncoderPinB) == LOW) EncoderPos--; else EncoderPos++; } } // Print a double value onto the serial stream // This is from the Arduino.cc forum void PrintDouble( double val, byte precision) { Serial.print (int(val)); //prints the int part if( precision > 0) { Serial.print("."); // print the decimal point unsigned long frac; unsigned long mult = 1; byte padding = precision -1; while(precision--) mult *=10; if(val >= 0) frac = (val - int(val)) * mult; else frac = (int(val)- val ) * mult; unsigned long frac1 = frac; while( frac1 /= 10 ) padding--; while( padding--) Serial.print("0"); Serial.println(frac,DEC) ; } } However, when I turned on the motor and run the wheel, the serial monitor can only detect velocity = 0.000. I don't know what went wrong. Appreciate your help. Thanks
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Sr. Member
Karma: 12
Posts: 327
The last thing you did is where you should start looking.
|
 |
« Reply #1 on: January 10, 2013, 02:01:14 am » |
Not knowing about this device, I would first see if I was getting an output form the encoder. Would you confirm with a scope that the signal going to the Arduino is indeed there? Also, show us your schematic for this project.
|
|
|
|
|
Logged
|
|
|
|
|
South Texas
Offline
God Member
Karma: 8
Posts: 976
|
 |
« Reply #2 on: January 10, 2013, 06:10:44 pm » |
Not knowing what type of outputs your encoder has. Are they TTL (5V) or are they differential? Differential outputs may not have enough voltage swing. If that is the situation then you would need a differential reciever to convert to a 5V TTL level signal for the Arduino.
I have used that code with an encoder so I know it works.
|
|
|
|
|
Logged
|
|
|
|
|
Left Coast, CA (USA)
Offline
Brattain Member
Karma: 279
Posts: 15310
Measurement changes behavior
|
 |
« Reply #3 on: January 11, 2013, 11:17:03 am » |
Not knowing what type of outputs your encoder has. Are they TTL (5V) or are they differential? Differential outputs may not have enough voltage swing. If that is the situation then you would need a differential reciever to convert to a 5V TTL level signal for the Arduino.
I have used that code with an encoder so I know it works.
The spec sheet shows the differential outputs working at the same output voltages as the single ended outputs, both TTL levels. So he only needs to wire up to the A+ and B+ output signal lines to the arduino if he indeed has the differential output model and it will then operate just like the single ended output model. Lefty
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Tesla Member
Karma: 71
Posts: 6596
Arduino rocks
|
 |
« Reply #4 on: January 12, 2013, 06:18:49 pm » |
The min output HIGH is 2.4V, not enough, although typical figure is 3.4V (just enough), for the single-ended or differential output version.
The ATmega needs a minimum of 3V to guarantee reading HIGH. In general TTL levels are not compatible with CMOS without a level shifting circuit or intermediate 74HCT buffer chip (a 74HCT14 schmitt-trigger inverter is often used to map TTL to CMOS levels at 5V). The 74HCT family of CMOS logic has TTL-compatible input thresholds.
Having said all that we I'm talking worst-case here - it is likely to work as is, but its worth checking with a meter that the HIGH output voltage level is more like 3.5V than 2.4V
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 6
|
 |
« Reply #5 on: January 13, 2013, 03:46:47 am » |
The min output HIGH is 2.4V, not enough, although typical figure is 3.4V (just enough), for the single-ended or differential output version.
The ATmega needs a minimum of 3V to guarantee reading HIGH. In general TTL levels are not compatible with CMOS without a level shifting circuit or intermediate 74HCT buffer chip (a 74HCT14 schmitt-trigger inverter is often used to map TTL to CMOS levels at 5V). The 74HCT family of CMOS logic has TTL-compatible input thresholds.
Having said all that we I'm talking worst-case here - it is likely to work as is, but its worth checking with a meter that the HIGH output voltage level is more like 3.5V than 2.4V
Do you mean that I need to increase the output voltage from the encoder to make it work?
|
|
|
|
|
Logged
|
|
|
|
|
United Kingdom
Offline
Faraday Member
Karma: 130
Posts: 4644
|
 |
« Reply #6 on: January 13, 2013, 04:12:52 am » |
The worst-case high level output (2.4V) is given at 20mA load, whereas the Arduino presents only a tiny load. So I very much doubt that insufficient high level output voltage is the problem. Nevertheless, I suggest you change the pin mode of the two encoder input pins to INPUT_PULLUP to be safe.
My guess is that one of the four wires between the encoder and the Arduino is not properly connected.
|
|
|
|
|
Logged
|
Formal verification of safety-critical software, software development, and electronic design and prototyping. http://www.eschertech.com
|
|
|
|
Offline
God Member
Karma: 9
Posts: 836
|
 |
« Reply #7 on: January 13, 2013, 07:01:53 am » |
I've seen it recommended, that the variable accessed in the interrupt routine should be declared "volatile", although whether it matters in this case, I don't know.
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Tesla Member
Karma: 71
Posts: 6596
Arduino rocks
|
 |
« Reply #8 on: January 13, 2013, 07:28:00 am » |
I've seen it recommended, that the variable accessed in the interrupt routine should be declared "volatile", although whether it matters in this case, I don't know.
If a variable is used both in an interrupt routine and in the rest of the sketch you make it volatile - otherwise the compiler might do the wrong thing.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 6
|
 |
« Reply #9 on: January 13, 2013, 11:56:22 pm » |
I have checked the output voltage of the encoder using a scope and it is shown that the output voltage is always at 3.7 V, regardless the position of the wheel. What could be the cause of this problem?
|
|
|
|
|
Logged
|
|
|
|
|
United Kingdom
Offline
Faraday Member
Karma: 130
Posts: 4644
|
 |
« Reply #10 on: January 14, 2013, 02:01:01 pm » |
Are saying that when the code wheel rotates relative the mounting base of the encoder, the outputs don't change? If so, check that the ground connection between the encoder and the Arduino is good.
|
|
|
|
|
Logged
|
Formal verification of safety-critical software, software development, and electronic design and prototyping. http://www.eschertech.com
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 6
|
 |
« Reply #11 on: January 14, 2013, 10:24:06 pm » |
Are saying that when the code wheel rotates relative the mounting base of the encoder, the outputs don't change? If so, check that the ground connection between the encoder and the Arduino is good.
Checked the ground and the outputs work just fine from the scope, however the serial output still says 0 velocity
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 6
|
 |
« Reply #12 on: January 15, 2013, 12:43:25 am » |
Solved, thanks
|
|
|
|
|
Logged
|
|
|
|
|
South Texas
Offline
God Member
Karma: 8
Posts: 976
|
 |
« Reply #13 on: January 15, 2013, 10:28:42 am » |
Solved, thanks
How? WHat was the problem?
|
|
|
|
|
Logged
|
|
|
|
|
|