AMT203 Capacitive Encoder - Driver

I’m trying to write a driver for [url]http://www.cui.com/product/components/encoders/absolute/modular/amt20-v-kit[/url]. Now, the device is supposed have “SPI configurable settings” (see page 1 of the datasheet) however, there is no application note that I can find that specifies how to do this.

So far I have figured out that it’s about writing values to the eeprom. I can read and write the eeprom however what I don’t know is which locations to write with what value. From reading the eeprom, I have determined that that there are 14 addresses that have a value other than 255.

eeprom[128] = 3
eeprom[129] = 21
eeprom[243] = 1
eeprom[244] = 5
eeprom[245] = 8
eeprom[246] = 8
eeprom[247] = 197
eeprom[248] = 0
eeprom[249] = 0
eeprom[250] = 231
eeprom[251] = 6
eeprom[252] = 32
eeprom[253] = 6
eeprom[254] = 207

The last 2 values (253 and 254) control the zero offset so that you can zero the encoder. This is settable by issuing the command 0x70. I learnt this from the app notes of the demo board ([url]http://www.cui.com/product/resource/pdf/amt203-dmk-appnote.pdf[/url]).

There is also a user guide for the demo board ([url]http://www.cui.com/product/resource/pdf/amt203-demo-kit-user-guide.pdf[/url]), which shows how to change the configuration. I am interested in changing the encoder configuration (page 4). It seems that what I need to write is one of the values from the resolution table. It appears that the last 4 bits controls the resolution (B3 to B0) while the 5th bit controls the sample interval, normal or fast mode (see resolution table page 4).

I don’t know what the default values of the encoder are. It was purchased as a kit so the default value is not specified in any datasheets. The module itself can be purchased pre programmed with a default value.

In the experience you guys have (i.e. the community) how should I go about solving this problem:

  1. Purchase the demo board + logic analyzer to reverse eng. the values?
  2. Purchase one with the correct default value then read it’s eeprom?
  3. Nag the manufacturer with emails until they send me the info?
  4. Attempt to brute force one of the 12 values in the list above until it appears that I have found it (this could destroy the device)?
  5. Give up and die?

If someone looks over the datasheets and finds something I missed, that would be helpfull also.

FYI here is the driver to date


using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using System.Threading;


namespace AMT203 {
    public class Program {
        public static void Main() {
            SPI.Configuration amt =
             new SPI.Configuration(FEZCerbuino.Pin.Digital.D10,
             false, // Chip Select, active-low
             0, // millisecond setup time
             0, // millisecond hold time
             false, // Clock low on idle
             false, // Data valid on falling edge
             1000, //1000Khz
             SPI.SPI_module.SPI1);
            SPI spiBus = new SPI(amt);

            WaitForAMT203(spiBus);
            byte[] eeprom = ReadAMT203EEPROM(spiBus);
            for (int i = 0; i < eeprom.Length; i++) {
                if (eeprom[i] != 255) {
                    Debug.Print("eeprom[" + i.ToString() + "] = " + eeprom[i].ToString());
                }
            }
            uint position = ReadAMT203Position(spiBus);
            SetAMT203ZeroPosition(spiBus);
            byte[] newEeprom = ReadAMT203EEPROM(spiBus);
            uint newPosition = ReadAMT203Position(spiBus);
        }

        public static void SetAMT203ZeroPosition(SPI bus) {
            byte[] rx = new byte[1];
            byte[] setZeroPoint = new byte[] { 0x70 };
            byte[] noOperation = new byte[] { 0x0};
            bus.WriteRead(setZeroPoint, rx);
            rx[0] = WaitForAMT203(bus);
            while (rx[0] != 0x80) {
                bus.WriteRead(noOperation, rx);
            }
        }

        public static byte WaitForAMT203(SPI bus) {
            byte[] rx = new byte[1];
            byte[] noOperation = new byte[] { 0x0 };
            const byte AMT203_NOTHING_IN_FIFO = 0xA5;
            do {
                bus.WriteRead(noOperation, rx);
            } while (rx[0] != AMT203_NOTHING_IN_FIFO);
            return rx[0];
        }

        public static uint ReadAMT203Position(SPI bus) {
            uint position = 0;
            byte[] rx = new byte[1];
            const byte AMT203_NOTHING_IN_FIFO = 0xA5;
            byte[] readPosition = new byte[] { 0x10 };
            byte[] noOperation = new byte[] { 0x0 };

            bus.WriteRead(readPosition, rx);
            while (rx[0] == AMT203_NOTHING_IN_FIFO) {
                bus.WriteRead(noOperation, rx);
            }
            if (rx[0] == readPosition[0]) {
                bus.WriteRead(noOperation, rx);
                position = (uint)(rx[0] << 8);
                bus.WriteRead(noOperation, rx);
                position |= (uint)rx[0];
            }
            return position;
        }

        public static byte[] ReadAMT203EEPROM(SPI bus) {
            byte[] noOperation = new byte[] { 0x0 };
            byte[] eeprom = new byte[255];
            byte[] readEpromCommand = new byte[] { 0x90 };
            byte[] one = new byte[] { 0x1 };
            byte[] rx = new byte[1];
            byte[] tx = new byte[1];

            const byte AMT203_NOTHING_IN_FIFO = 0xA5;

            for (byte i = 0; i < eeprom.Length; i++) {
                tx[0] = i;
                bus.WriteRead(readEpromCommand, rx);
                bus.WriteRead(tx, rx);
                bus.WriteRead(one, rx);
                bus.WriteRead(noOperation, rx);
                while (rx[0] == AMT203_NOTHING_IN_FIFO) {
                    bus.WriteRead(noOperation, rx);
                }
                if (rx[0] == readEpromCommand[0]) {
                    bus.WriteRead(noOperation, rx);
                    eeprom[i] = rx[0];
                }
            }
            return eeprom;
        }
    }
}

Well it seems that option 2) Purchase one with the correct default value then read it’s eeprom is out, since I can’t find one to buy.

@ Mr. John Smith - You wrote 'I don’t know what the default values of the encoder are. '
From Datasheet page 3, under ‘Part Number Key’ the first XXXX group appears to define the default resoluion.
From the User’s guide, page 4, you may determine the corresponding binary value, and then search among the
12 bytes which one contains that value, perhaps masked by 0x15 in case other bits were used. With some luck,
only one byte may pass the filter.

@ Mr. John Smith, I would suggest you contact the manuf, to get the full data sheet. I have ran across this several times where manuf, will publicly release a trimmed down version of the data sheet, and you need to contact them to get the full one.

@ SouthernStars - the device that comes with the kit doesn’t have a part number, so I can’t lookup what the default value is… Also, it seems that they don’t sell the individual parts on mouser or digikey anymore.

I got a replay from cui today. they say that they don’t give out that information because it requires writing to the eeprom. They suggest that I purchase the demo board to change the resolution. I told them that I need to be able to change it on the fly, AND their product lit says that the resolution can be changed via spi. They also used to give out the firmware that was on the demo board as reference, but it seems like they don’t anymore.

@ Mr. John Smith - Perhaps you may rotate the encoder by a known angle and read the values, and you will be able to guess the resolution and proceed as I proposed.

@ SouthernStars - Yea, that’s my only recourse at this point. However if the resolution isn’t set to a multiple of 200 (which I doubt it will be) then I’m back to square one.

This is a job for PulseCounter!

Well looks like the provider is going to help out. Also, the default resolution is 1024; which won’t work for me. Looks like I won’t need the pulse counter.

Well the maker responded, however they would prefer if the data didn’t end up public because its a non supported feature.