Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Getting range of 18-4095 #22

Closed
cranefist opened this issue Oct 15, 2022 · 31 comments
Closed

Getting range of 18-4095 #22

cranefist opened this issue Oct 15, 2022 · 31 comments
Assignees
Labels
question Further information is requested

Comments

@cranefist
Copy link

cranefist commented Oct 15, 2022

Hello

Great to find a fresh library for this chip. I switched using this library, and ran across a weird thing.

I get a range of 18-4095. Any idea why this is happening?

Im moving a stepper motor slowly, and reading it via serial monitor. It shows all the steps clearly, with 1 increments. Just somehow starts at 18.

Can the filters affect this? These are my settings:

as5600.setPowerMode(AS5600_POWERMODE_NOMINAL);
as5600.setHysteresis(AS5600_HYST_OFF);
as5600.setSlowFilter(AS5600_SLOW_FILT_2X);
as5600.setFastFilter(AS5600_FAST_FILT_LSB10);
@RobTillaart RobTillaart self-assigned this Oct 15, 2022
@RobTillaart RobTillaart added the question Further information is requested label Oct 15, 2022
@RobTillaart
Copy link
Owner

Thanks for the issue,
Only the basic functionality is tested by myself as I only have test hardware recently.
So I cannot give an answer now, and I will dive into the datasheet a.s.a.p. I recall that the number 18 was mentioned.

@cranefist
Copy link
Author

cranefist commented Oct 15, 2022

It seems to be fluctuating, i noticed this when i set it to home at under 10. And it never reached it.

But occasionally i do get 10. Not sure what this is about, there was something in the datasheet about rotations.

I noticed in the datasheet, that if used via 3.3v the 3.3v & 5v should be connected. I have never done this before and used these... and even now it seems to work kinda fine.

Seems the pull up resistors are connected only to the 5v line.. so they were out of action. This board seems to have 10k pull ups, datasheet says 4.7k for 3.3v so they are sized probably to fit both voltages.

@cranefist
Copy link
Author

cranefist commented Oct 15, 2022

I soldered the 3.3v & 5v together. Ran another test, this time at 256 microsteps.. slowly.

The numbers stopped at 4095 for some time, and then skipped to 10!.. really weird.

I will try this again.

Redid the test, the same result. Stops at 4095 for some time and next up is 10.

Third test, default settings. Removed all the settings i had. Same result.

@cranefist
Copy link
Author

cranefist commented Oct 15, 2022

Tested on the Seeduinos AS5600 library that i used before, it works.. but it also has a weird issue.

This is how it goes from 4095 to 0 :

4095
4095
4095
4095
255
0
0
0
0
3840
4095
255
0
0
0
0
0
0

I think you have a bug in your library.

Maybe its about this:

ANGLE/RAW ANGLE Register
The RAW ANGLE register contains the unscaled and unmodified
angle. The scaled output value is available in the ANGLE register.

Note(s): The ANGLE register has a 10-LSB hysteresis at the limit
of the 360 degree range to avoid discontinuity points or
toggling of the output within one rotation.

Page 19

Am i reading the wrong output with readAngle()?

@cranefist
Copy link
Author

cranefist commented Oct 15, 2022

Ok, that was the issue. I was reading the wrong output.
With rawAngle() i get what i expect. And none of the weird noise that i had with sparkfuns library, probably because i can now set the filters. Just normal flip-flopping, as the stepper is running on 32 microsteps really slowly so it has higher resolution than on this encoder.

4095
0
4095
0
4095
4095
4095
4095
0
0
0
0
0
0
0
4095
0
4095
0
0
0
0
0
0
4095
4095
0
0
0
0
0
0
0
0
0
0
0

@cranefist
Copy link
Author

Yeah, i think this works now!

I was worried that this encoder cant keep up, as a lot of people seem to be under the impression that this is only a slow speed encoder.

But im running this up to 25rps and now it seems to keep track. With sparkfuns library i had issues as it occasionally messed the rotation calculations, and now i know it was the lack of filtering that caused it.

Im running this at 900 000khz on ESP32.

I would recommend adding a linear counter in your library, and also output based on steps. You already have degrees, so why not steps directly. Just for user convenience and laziness.

Aaand, just when i got this working..i find this : https://www.aliexpress.com/item/1005004570883506.html
Cheap 14bit encoder, rated up to 55'000RPM!
"Replaces AS5600 Module" nooo....

@RobTillaart
Copy link
Owner

Yeah, i think this works now!

Great!
Would you mind posting your - minimized - sketch, so I can add it to the examples?

I would recommend adding a linear counter in your library, and also output based on steps. You already have degrees, so why not steps directly.

Would that be something like

int32_t getCounter();  returns  -2 billion .. 2 billion   (do a mod 4095 for position?)
void resetCounter();

or how would you prefer the API calls?
You can create a PR (pull request) if you already figured it out.

@RobTillaart
Copy link
Owner

Aaand, just when i got this working..i find this : https://www.aliexpress.com/item/1005004570883506.html
Cheap 14bit encoder, rated up to 55'000RPM!
"Replaces AS5600 Module" nooo....

Found the datasheet, - http://www.magntek.com.cn/upload/MT6701_Rev.1.0.pdf
I might make an (I2C) library for that MT6701 in the future.

@cranefist
Copy link
Author

cranefist commented Oct 15, 2022

I celebrated a bit too early it seems, it still occasionally fails.. i have been using this code to keep track of linear movement, its from an example of the original old as5600 library and has worked thus far on my applications. But now as i need more speed, it fails.

I need to replace this with something that cant fail, as i know the direction the motor is moving.. i can probably use that information to come up with a more robust way of keeping track of the total amount of steps.

As magnetic encoder is absolute, the only real problem to solve is to keep track of revolutions. As the stepper already knows its position, all i need is a back up if it stalls and loses count.

output = as5600.rawAngle();                 // get the raw value of the encoder                      
  
  if ((lastOutput - output) > 2047 )        // check if a full rotation has been made
    revolutions++;
  if ((lastOutput - output) < -2047 )
    revolutions--;
    
position = revolutions * 4096 + output;     // calculate the position the the encoder is at based off of the number of revolutions

lastOutput = output;                        // save the last raw value for the next loop 

encoderStep = (position - zeroPosition) / (4096 / 200); // converts to full steps & deducts starting point.

@cranefist
Copy link
Author

cranefist commented Oct 15, 2022

Aaand, just when i got this working..i find this : https://www.aliexpress.com/item/1005004570883506.html
Cheap 14bit encoder, rated up to 55'000RPM!
"Replaces AS5600 Module" nooo....

Found the datasheet, - http://www.magntek.com.cn/upload/MT6701_Rev.1.0.pdf I might make an (I2C) library for that MT6701 in the future.

Going to pick one of those up for testing, seems really interesting. The same seller also has a more expensive MT6825:
https://www.aliexpress.com/item/1005004647993391.html
That thing also seems really interesting, datasheet says 18bits!
http://www.magntek.com.cn/upload/MT6825_Rev.%E8%8B%B1%E6%96%871.8.pdf

And also seems to be more robust as it only monitors X/Y magnetic field. 3 or 4 wire SPI.
Seems he is the only one selling modules with these chips.

@RobTillaart
Copy link
Owner

I need to replace this with something that cant fail, as i know the direction the motor is moving.. i can probably use that information to come up with a more robust way of keeping track of the total amount of steps.

That can only be done by measuring the angle at least 3x per rotation. In theory 2 but in practice maybe even 4x.
If you need to measure e.g. 500 RPM you have to measure 1500 times per second. (Yes if you take into account the fact that you know the rotation direction "1++" sample per rotation (e.g. 700 samples) would work).

With 3 samples per rotations the angle is max 120° so a full rotation is always detectable. These samples have to be spaced in time (roughly) equally to work. This implies that your code should have no blocking code to get this timing right.

(thinking out loud)

  • a separate thread on e.g. an ESP32 with 2 cores can have a continuous background process.
  • additional (UNO) processor to handle the sensor, and even provide an interrupt pulse to the "main" processor.
  • increase the Wire.setClock() so samples can be made faster might help. 400KHz is 2~3x as fast as 100 KHz.

@cranefist
Copy link
Author

cranefist commented Oct 16, 2022

Im measuring once per 1ms, and i'm exactly using 2 cores on ESP32. So its running on a separate core with high priority. Wire clock is set at 900 000Khz. The sensor can do 1Mhz, but i got errors at 1Mhz and with 900 000Khz its smooth sailing.

I use 1kOhm pull ups on the ESP32 based on this : espressif/arduino-esp32#6444 (comment)

Im lagging only 5 steps (5 steps is exactly 1ms) if moving at 5000steps per second (full steps, so 5000/200=25rps), so i can get 40 measurements per rotation.

So the speed should not be an issue, i should be able to measure much faster if needed. Even now i think the 1ms comes from me using vTaskDelay(1), even though it should not be exactly 1ms. I think the sensor can go faster.

I think the issue i'm having is the noise when moving from 4095 to 0. How to handle the possibility of random change of getting 4095 when you should be getting 0?

@RobTillaart
Copy link
Owner

How to handle the possibility of random change of getting 4095 when you should be getting 0?

If you can make 40 samples per rotation (~ 1 sample every 9°) , you could thinking of skipping the measurements in the "danger zone". E.g if rawAngle is between 4090 and 5.

@cranefist
Copy link
Author

How to handle the possibility of random change of getting 4095 when you should be getting 0?

If you can make 40 samples per rotation (~ 1 sample every 9°) , you could thinking of skipping the measurements in the "danger zone". E.g if rawAngle is between 4090 and 5.

Yes, you are thinking this in degrees. Is that how its usually done? with optical encoders?

The example code i'm using, is probably more suited for knobs etc. And it exactly measures the move from 4095 to 0.

While i should indeed think this in degrees and check the rotation at some other point.

@RobTillaart
Copy link
Owner

Datasheet states that sampling rate is 150 us. So the sensor can in theory make 6000 samples / second.

@cranefist
Copy link
Author

Datasheet states that sampling rate is 150 us. So the sensor can in theory make 6000 samples / second.

Yes, exactly. Even the slow 2x filter could do 0.286ms. So the sensor should be plenty fast.

@RobTillaart
Copy link
Owner

Optical encoders mostly use interrupts. When a step is made, or after N steps, an interrupt is generated.
This allows very precise position/ angle measurement. For RPS / speed measurement too much interrupts gives problems.

@RobTillaart
Copy link
Owner

That MT6701 sensor you mentioned, has an ABZ interface.
IIRC the Z pulse indicates a full rotation, while the AB pulses work like a rotary encoder.

@cranefist
Copy link
Author

cranefist commented Oct 16, 2022

ABZ interface

Yes, that seems to be what it is... i tried to do a quick google when i read about it thinking it was some sort of bus that i had not heard of. Already ordered one for testing, even the module is small enough to fit my use. As i tracked down these AS5600 modules that are only 15x15mm in size to fit my device. The only issue is, that on that MT6701, there are components on the backside.. that would be a problem for me. I dont have room for that.

I think i should be ok with as5600 for this project though, i only need precession of 200 steps. That's 20.48 clicks per step, that should be more than enough to cover the possible noise. If i have like a buffer of 5 clicks at full rotation, that would be only 1/4th of a full step. And set the measuring point based on the starting point so that it always lands between steps.. so that i wont ever have the possibility of stopping at the edge.

BTW. Can your library do wire & wire1 at the same time? I'm using two of these, one on wire and the other on wire1? Other tracks the motor, the other is just a knob. Previously i have used a crudely hacked version of the sparkfuns library that i did to accomplish this.

@RobTillaart
Copy link
Owner

(was occupied by gardening and some other libraries)

BTW. Can your library do wire & wire1 at the same time?

Yes, that should work.
Not tested with this library but I use the same construction in all my I2C libs.
If it doesn't work please let me know.

@cranefist
Copy link
Author

cranefist commented Oct 16, 2022

Ok i will try that.

The problem seems to not be the transition from 4095 to 0, but just random noise that can happen. No matter what filters i use, this just happens randomly. Tested all the way up to 16x slow filter.

Here is an example printout of moving down at constant speed, from somewhere it gets weird numbers and counts one revolution up.

47-4051
57-4048
3021+969
54-4057

These are the lastOutput & output from the code above. The + sign just means that its increasing revolutions, - sing outputs are decreasing.

@cranefist
Copy link
Author

Ok, finally solved it.
It was exactly the thing that was bugging me when i found your library, that DIR pin.

I just figured i don't need it, but apparently what i had was essentially a dark matter detector.. and when a dark matter particle hit it, it changed direction.

Good thing its now back to being a normal encoder.

If you want to improve your library, just type in big bold letters that you need to solder that DIR pin & 3.3v to 5v if you use 3v.

I had not seen anything about that DIR pin before i found your library, and its really hard to understand what the issue is as its so random. I thought i only needed it for analog use.

So the speed is not an issue, this can track much faster speeds if needed. I'm still using 4x slow filter at this speed.

@RobTillaart
Copy link
Owner

what i had was essentially a dark matter detector..

😂 you're in for the next Nobel prize!

If you want to improve your library, just type in big bold letters that you need to solder that DIR pin & 3.3v to 5v if you use 3v.

OK, will add the following to the readme.md.

From the datasheet, page 30

Direction (clockwise vs. counterclockwise)
The AS5600 allows controlling the direction of the magnet rotation with the DIR pin. If DIR is connected to GND (DIR = 0)
a clockwise rotation viewed from the top will generate an increment of the calculated angle. If the DIR pin is connected
to VDD (DIR = 1) an increment of the calculated angle will happen with counterclockwise rotation.

@RobTillaart
Copy link
Owner

Please note that there is already an explanation of the use of the DIR pin in the readme.md.


The DIR (direction) pin of the sensor should be connected to:

  • GND = fixed clockwise(*)
  • VCC = fixed counter clock wise
  • a free floating IO pin of the processor = under library control.

In the latter setup the library can control the direction of
counting by initializing this pin in begin(directionPin),
followed by setDirection(direction). For the direction the
library defines two constants named:

  • AS5600_CLOCK_WISE (0)
  • AS5600_COUNTERCLOCK_WISE (1)

(*) if begin() is called without directionPin or with this
parameter set to 255, software direction control is enabled.

See Software Direction Control below for more information.


Software Direction Control

Experimental 0.2.0

Normally one controls the direction of the sensor by connecting the DIR pin
to one of the available IO pins of the processor.
This IO pin is set in the library as parameter of the begin(directionPin) function.

The directionPin is default set to 255, which defines a software direction control.
To have this working one has to connect the DIR pin of the sensor to GND.
This puts the sensor in a hardware clock wise mode, so it is up to the library
to do the additional math so the readAngle() and rawAngle() behave as
if the DIR pin was connected to the processor IO pin.

The gain is that the user does not need an IO pin for this,
which makes connecting the sensor a bit easier.

The user still calls setDirection() as before to change the direction.

TODO: measure performance impact.

TODO: investigate impact on functionality of other registers.


@RobTillaart
Copy link
Owner

I have updated the readme.md in the master branch.
No new release for now, as there is an update planned soon (extend the build-CI and a CHANGELOG file, no functional update).

@cranefist
Copy link
Author

cranefist commented Oct 16, 2022

Yes, i noticed it but still skipped it :) Just thought that it would be good to have it really clearly mentioned in the start. How to set up the hardware side. The DIR pin & 3.3v & 5v connection. If i make this mistake, i bet there are a lot of other people making the same mistake.

As it seems you cant leave it floating, that will lead to issues.

"a free floating IO pin of the processor = under library control." So i would maybe rephrase this part. Having the "floating" as third option might make it seem like you can just leave it floating and control it via the library.

I would have never noticed this if i had not tried to use it on this motor & found your library, as i have used these as dials.. and never did anything with the dir pin, i didn't even knew about its existence.

Really good thing. As if i had not learned this, my other project would have had random weird issues that i could not have been able to fix via software.

@RobTillaart
Copy link
Owner

have it really clearly mentioned in the start.

Check if I can move it up.

How to set up the hardware side.

I'll check if I can add some diagram.

"a free floating IO pin of the processor = under library control." So i would maybe rephrase this part.

Just updated that section, when I reread it, it looked at least ambiguous to say it nicely.

If you have time, would you read the current readme.md.
It is not my goal to redo the datasheet, however if phrases need a fix I like to hear them.

@RobTillaart
Copy link
Owner

@cranefist
Created a develop branch with a.o. a reorganized readme.md - story about DIR moved up.

@RobTillaart
Copy link
Owner

Merged, create a new 0.3.2 release

@RobTillaart
Copy link
Owner

@cranefist
Is your issue now solved ?
Or are there still questions?

@RobTillaart
Copy link
Owner

As I think the issue is solved I close it. Feel free to reopen it if needed, or open a new one if not related.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants