AS5601 sudden instability -- anyone else seen this?

I found that the AS5601 rotary Hall sensor was ideal for my needs (sensor for steering for my USBcycle project -- using a stock MTB as a USB game controller). It's a non-contact I2C rotary sensor with good resolution, and it's been reliable for quite a while in service. I attached the AS5601 eval board to the top of the fork so it rotates with the bars, while the magnet is mounted above in a fixed position.

I calibrated it manually using a diagnostic sketch that spits out angle readings to the serial monitor; I adjusted the rotation of the (diametrically-polarised) magnet until the range of travel of the handlebars produces a legitimate non-wrapping range of values from the encoder. (The last calibrated range, preserved in my code, was 1080 cts to 1880 cts -- with a mid point where you would expect it, at around 1480 cts)

All this has worked beautifully for months. But last night, something very odd happened. My steering suddenly went haywire -- steering L resulted in hard R lock etc. Today I started running diagnostics to find out what happened... and found to my amazement that the encoder has now changed its mind entirely about where the zero point is. The range of rotation angles which used to be legitimate has shifted significantly and now wraps near midpoint -- I'm not talking about a subtle drift here -- centre point is now more like 255 counts! The total range of angle values seems to be about the same, so I don't think it's dropping a bit or shifting a register or sending the bytes in the wrong order...

And no, it is not possible for the magnet to have rotated spontaneously to a new position: it's held down with double-sticky tape. The range of possible values looks about the same (0 to 2047), but zero point has rotated by some 1200 counts!

To call this surprising is understatement :slight_smile: I've been staring at it for about an hour muttering "It can't do that." :slight_smile:

Anyway, life goes on -- I am about to recalibrate from scratch -- but I'm deeply puzzled. Has anyone else seen an AS5601 device go radically unstable like this? Is there some other explanation? Am I missing something?

Encoder read code (based on Arduino library and example):

void readRotaryHall () {
  
// Quadrature enc with the AS5601 Hall position.
  Wire.beginTransmission(0x36);       // transmit to device as5601
  Wire.write(byte(0x0E));             // sets register pointer 
  byte result = Wire.endTransmission();    // stop transmitting
  Serial.print(F("    Result of tx to AS5601:  "));
  Serial.println(result);
//
  Wire.requestFrom(0x36, 2);         // request 2 bytes from as5601
  int reading = Wire.read();             // receive high byte 
  reading = reading << 8;            // shift high byte to be high 8 bits
  reading |= Wire.read();            // receive low byte as lower 8 bits
  // Serial.print(F("First RHall angle: "));
  rawSteerVal = reading/2;  
  Serial.print(F("    Value read from Rotary Hall:"));
  Serial.println(rawSteerVal);
(...)

SAMPLE OUTPUT TO MONITOR
    Result of tx to AS5601:  0
    Value read from Rotary Hall:266
    Result of tx to AS5601:  0
    Value read from Rotary Hall:266
    Result of tx to AS5601:  0
    Value read from Rotary Hall:266

Tazling:
I found that the AS5601 rotary Hall sensor was ideal for my needs (sensor for steering for my USBcycle project -- using a stock MTB as a USB game controller). It's a non-contact I2C rotary sensor with good resolution, and it's been reliable for quite a while in service. I attached the AS5601 eval board to the top of the fork so it rotates with the bars, while the magnet is mounted above in a fixed position.

I calibrated it manually using a diagnostic sketch that spits out angle readings to the serial monitor; I adjusted the rotation of the (diametrically-polarised) magnet until the range of travel of the handlebars produces a legitimate non-wrapping range of values from the encoder. (The last calibrated range, preserved in my code, was 1080 cts to 1880 cts -- with a mid point where you would expect it, at around 1480 cts)

All this has worked beautifully for months. But last night, something very odd happened. My steering suddenly went haywire -- steering L resulted in hard R lock etc. Today I started running diagnostics to find out what happened... and found to my amazement that the encoder has now changed its mind entirely about where the zero point is. The range of rotation angles which used to be legitimate has shifted significantly and now wraps near midpoint -- I'm not talking about a subtle drift here -- centre point is now more like 255 counts! The total range of angle values seems to be about the same, so I don't think it's dropping a bit or shifting a register or sending the bytes in the wrong order...

And no, it is not possible for the magnet to have rotated spontaneously to a new position: it's held down with double-sticky tape. The range of possible values looks about the same (0 to 2047), but zero point has rotated by some 1200 counts!

To call this surprising is understatement :slight_smile: I've been staring at it for about an hour muttering "It can't do that." :slight_smile:

Anyway, life goes on -- I am about to recalibrate from scratch -- but I'm deeply puzzled. Has anyone else seen an AS5601 device go radically unstable like this? Is there some other explanation? Am I missing something?

Encoder read code (based on Arduino library and example):

You may have executed a Burn_Angle Command see page 22 of the Data sheet. [v1-05] 2016-Feb-11

Chuck.

You may have executed a Burn_Angle Command see page 22 of the Data sheet. [v1-05] 2016-Feb-11

Can you think of any way this could happen by accident? Certainly my code never writes 0x80 into register 0xFF ... (this is the Burn Angle command), and I have never run any other code against this device. Moreover, the failure took place while in active use, i.e. with the existing code running.

I suppose if the I2C bus went wonky, a wrong value might get transmitted; but it seems like a huge coincidence for the bus to select the wrong register and the wrong value on the same transmission, and to pick the specific wrong values that would result in the Burn Angle command...

I have to agree w/you that what I have seen looks very much like a change in ZPOS, and the normal way that ZPOS would get changed would be the Burn Angle cmd. I just don't see how my code could possibly have done it -- the string 0xFF appears nowhere in the source :slight_smile: nor does 0x80.

Still scratching head...

You have it well defended against EMI?

-- You have it well defended against EMI?

Well no not really, except by physical isolation (it is at least a foot away from the main enclosure containing 2 Leos, etc). The cable is just a ribbon, not foil wrapped, no ground twisted around each signal, just a flying ribbon cable out in the air.

I think of EMI as random bit-mugging though -- again, what would be the odds on random noise just happening to generate two interactions (in the right order!) to set register and then send data, with just the right values to do a Burn Angle?

One reassuring thing about the datasheet is its claim that Burn Angle can only be executed 3 times. After that, presumably, the ZPOS is fixed for life. So this can only happen 2 more times at most :slight_smile: I know it's a bit sloppy and lazy relying on this rather than figuring out the problem, but it seems to be well beyond my limited trouble shooting skills so I'm glad this limit is imposed by the mfr.