Encoder interrupt problem on svp1284p

Hi again, some more questions.

19:1 Metal Gearmotor,
19x64= 1216 counts per revolution would be some 4-5 m in my case with 19:1

Returns the number of counts measured on M1 or M2. For the Pololu wheel encoders, the resolution is about 3mm/count, so this allows a maximum distance of 32767 × 3mm or about 100m. For longer distances, you will need to occasionally reset the counts using the functions below.

In a future release might it be possible to throw in a divider like 2, 4, 8, 16 when you do the encoder init to get some more distance out of it?
Or is all hardcoded stuff “in the bottom”?
Distance is of more value than resolution of 1216 on a single revolution.

I do not think it would work with some sort of external counter between motor encoder and the input on the SVP acting as a divider or to fix this?

When you do the encoders_init(16,17,18,19);
Could you do like encoders_init(16,17,0,0); to save two interrupts, just have need for one motor and more need of a free interrupt.

This section of the library makes uses of pin-change interrupts to quickly detect and record each transition on the encoder. Specifically, it uses the AVR’s PCINT0, PCINT1, and PCINT2 (and PCINT3 on the Orangutan SVP and X2) interrupts, and it will conflict with any other code that uses pin-change interrupts (e.g. OrangutanPulseIn).

What is a good policy switching direction on that motor, just go via 0 and then -255 or involve some time as well so I do not get a harmful current spike.

Would a mini glue on heatsink on the H bridge do any noticeable good?

Last,
Just unpacked and did setup 19:1 Metal Gearmotor 37Dx52L mm with 64 CPR Encoder to the SVP downloaded the wheelencooder test with a simple motor start added to it running for some seconds.
Well the encoder routine just tally up to 11110 with a constant Error 1.
It does not matter if anything is connected or not (hall sensor), same behavior.

#include <pololu/orangutan.h>
#include <avr/interrupt.h>

int main()
{
  unsigned long time = 0;
  encoders_init(16,17,18,19); // the Arduino numbers for ports PC2 - PC5
  set_motors(200, 0); 

  while(1)
  {
    lcd_goto_xy(0,0);
    print_long(encoders_get_counts_m1());
    print(" ");

    if(encoders_check_error_m1())
    {
      lcd_goto_xy(0,1);
      print("Error 1");
    }
	time++;
	if (time >100)
		  set_motors(0, 0); 
    delay_ms(50);
  }
}

Please advice,

Regards,
ted


PS,
Federal Express is just outstanding as a shipping choice, phones up to check before driving out on the last leg if there is a number to do so and always extremely quick and on time.

Hi ted,

You can connect the encodes to the 1284P’s auxiliary processor. You will then need to set the mode to enable the encoders: svp_set_mode(SVP_MODE_ENCODERS). Then use svp_get_counts_ab() and svp_get_counts_cd() to get the current count. If you want to track a long distance, then use svp_get_counts_and_reset_ab() and svp_get_counts_and_reset_cd() to add the current value to an accumulator in your app.

Mike

Thanks for the reply mike31416!
I will try that tomorrow.
I took for granted that the sample code for the 1284p would be utilizing that feature, my bad not reading up enough but the good news that the “toys” might be ok after all.

Still also interested in a opinion on questions not covered in that answer if some kind soul have time. (still noob so sorry if stupid questions :wink: )

ted

I don’t know if we would do that. In the near future, if you want more than 16-bit resolution, you could create two 32-bit integers ("signed long"s) in your code to hold the number (and sign) of the counts from each encoder. But I don’t actually think that would be useful because usually what people want to do with encoders is not just add up tens of thousands of encoder counts, they want to compute the position and heading of their robot. To do that, you would want to read the encoders as often as possible, use the counts to incrementally update your position and heading information, and reset the counts to 0 whenever you read them. If that’s how you are using your encoders then 16 bits of resolution should be enough for you. Does this make sense?

If you are using the PololuWheelEncoders library then you can give an invalid pin number in order to avoid enabling extra interrupts. However, 0 is a valid pin number, so you should use something like 40 instead. However, you have an Orangutan SVP so you should connect the encoders to the auxiliary processor and use the Orangutan SVP encoder functions, not the PololuWheelEncoders library.

Implementing gradual acceleration and deceleration would be a good idea to reduce electrical noise and also to help prevent your wheels from slipping (which would make your encoder counts less useful). What voltage are you powering the motors at?

If your motor driver chips are getting very very hot, then yes. But keep in mind that electronic parts can still function even if they are hotter than anything you would want to touch, and I don’t think that is likely to happen with these motors.

I’m not sure why you are getting that error. If you really want to I can help you figure it out, but I think that you should instead connect your encoders to the auxiliary processor and try running the code that I posted here:

If that doesn’t work, let us know all the connections you made, everything you did, the expected behavior, and the actual behavior you got out of the SVP.

–David

Thank you very much for taking the time and answer me David.E.Grayson.

I actually wanted less pulses per revolution with the suggestion made like divider 16 64/16=4 per revolution.
Any way singed long works fine with the empiric testing made today. (no robot project)

I supply the SVP1284 with 13.2V.
It’s not a robot project but the motor will switch both speed and direction (all runnable voltage intervals) this on a frequent irregular base.
What I am after is the safest shortest way to go full 255 to -255 sort off, and with that going on in a few seconds intervals, that is worst case.
I guess with using PWM it would be safe go at 255 with 13.2V on the 12V motor or?

The error was because I did not realize that the sample code was not using the sub processor but the main processor it self, and looking 16,17,18,19 was pins in use for the display :smiley: (never asume anything :wink: )
Using svp_set_mode(SVP_MODE_ENCODERS); it works fine.


New questions,
-Will the svp_set_mode(SVP_MODE_ENCODERS); use up any interrupts at all on the main processor when wheel encoding is handled on sub processor and just read via software calls and no overflow interrupt generation to “bother” the main processor?
-With set_motors(x, y); call I guess you never achieve a brake situation?

Regards,
ted

These motors have a stall current of 2.5 A at 6 V, which means the stall current at 13.2 V will be over 5 A. The SVP can handle peak currents up to 6 A and continuous currents of 2 A. If the motors are going to be stalled for long periods of time then the SVP can’t handle running them at full speed (255), but if they have relatively light loads and the current for each motor is under 2 A most of the time then the SVP should be able to handle it.

No.

Specifying a motor speed of zero puts that motor in to a brake state (both outputs go low). For intermediate speeds, the motor PWMs between the driving state and the braking state.

–David

Hello.

You should also avoid going directly from full-speed forward to full-speed reverse as this can cause the motor to briefly draw nearly twice the stall current, which would well exceed the driver’s 6 A maximum when your input voltage is 13 V. Inserting a braking period before changing direction and/or using gradual acceleration (rather than setting the motor speed directly to 255) will help decrease the magnitude of current spikes.

Also, what are you using for your power source and how long are your power leads? You’re getting dangerously close to 15 V maximum voltage limit of the SVP’s motor drivers. Exceeding this limit can permanently damage the driver, so you need to be wary of noise on your VIN line that could push it over the absolute maximum. Also, you should be aware of LC voltage spikes, which can occur when you apply power. Given how little margin you have, please make sure you’re taking steps to avoid such voltage spikes (or decrease your input voltage so you have a greater safety margin).

- Ben

Once again Thanks David and Ben for your answers.

It’s all driven by a very high quality 13.2V 3A PSU, so in it self there are limiting there.
Have made the skeleton mechanic and with just some empiric tests with some skeleton code it’s a comfortable margin current wise monitoring the current drawn with the built in current sensor with a current shut routine (load will vary a bit), it’s a strong motor.

It’s not that time sensitive, so go via set_motors(0, 0); with some ms delay is no problem.

My encoder counter routine (signed long) does work, but of some reason “halting” motor trying preset values was strangely unprecise “overshooting” preset value, not much code and no delays as such, probably some bad coding made by me :smiley: , will test more tomorrow.

I guess doing a “print” just changes things somewhere in a memory area and not “hanging” around waiting? or same for read analogue? pin change? and should not cause any delay in code loop?

Thanks for bearing with a newbie.

Regards,
ted

I’m not sure I understand what you’re trying to ask here. Certain library function calls take longer than others. The function that clears the LCD, for example, blocks program execution for around 1 ms. The time it takes to read an analog input depends on the way you read it. You can set it up to start a conversion, go on to do other things, and then check the conversion result once it finishes (i.e. don’t block program execution), or you can start the conversion, wait for it to finish, and then return the result. The Pololu AVR Library provides functions for doing it both ways. If you use the function that waits for the conversion to finish, it will block program execution for approximately 100 us. If you use the function that averages multiple samples, it will block program execution for approximately 100 us per sample in the average.

If you want your motor to stop at a precise position based on encoder feedback, you should look into using PID.

- Ben

Hey guys, you are real quick answering here, really appreciated Thanks Ben!

Thinking about it now it overshoot about 5000, but on a 19/1 1216 this is just ~1/5 of a revolution which is good enough in this case, got mentally “hooked” on the number not giving it thought, I blame Friday and tired :wink:
It’s also possible to do some empiric testing of overshoot for different V to better that up by roughly “predicting” overshoot and take that in account.

I do not know what PID is? but I am always eager to learn so I will look into that and also for fun of it do some tests on execution time on the different parts/calls done.

And I will definitely check out this,

I think I am good for now, thanks.
If this turns out well and functioning in the end I will post a video of it for your amusement, I think you might appreciate the humour in my project :wink:

ted

I suggest you try googling around for resources on PID, and we have some discussion of PID in the 3pi user’s guide. If you have any questions, please ask.

We’d certainly enjoy seeing how your project turns out!

- Ben