Reading Grizzly iGaging DRO Scales with Arduino

Thursday, January 19, 2012

As I'm waiting for the parts for my do-it-yourself Android DRO, I'll start doing some proof-of-concept prototypes with the parts I already have. So, first things first - we need to figure out how to read the Grizzly/iGaging scales. The easiet way to reverse engineer the protocol is to connect a logic analyzer (Open Lgic Sniffer in my case) and see what's happening in the wires. The screenshot below gives a good idea how those things tick (no pun intended).

iGaging 21 Bit protocol captured by Open Logic Sniffer
21 Bit Protocol Capture

After some tinkering and experimentation I've determined that the specs for those scales are as follows:

Specifications:

  • Supply voltage - 3V
  • Clock frequecy - 9KHz
  • Clock source - DRO Display/Arduino
  • Read frequency - 150 Hz
  • Data format- 21 bit serial, LSB first, one's compliment
  • Resolution - 2560 PPI
  • Mode - absolute position

Wire functions:

  • Red - Vdd (3V)
  • White - Clock
  • Green - Data
  • Black - Ground

This gives us enough information to put together a quick Arduino sketch and try reading the position. We will need 4 digital pins for this project: one pin will provide clock output to the three scales and three ports will read the data. An important thing we need to keep in mind is that Arduino's ports supply 5V, but the scales are not 5V-tolerant. An easy workaround is to use a voltage divider on the clock pin. The data pins won't be a problem, since ATMega micro controller can work with inputs under 1V (per ATMega 2650 datasheet). The code is fairly simple: we will pulse the clock pin 21 times, read the state of the three data pins and store the result in "long" signed integer.

Incidentally the data sent by the scales is represented in one's compliment format with least significant bit first. This means that we will need to read the first 20 bits and left-shift them in. The last (21st) bit will determine the sign. If the bit is HIGH, the bits left to it will be set to all "1"s, otherwise they will stay at 0.

The hardware will be fairly simple. The only thik we need to take care of is the voltage division to get Arduino's 5V output to a safer value. I have a pile of 10K and 20K resitors, so I will use those but you can use any two resistors that satisfy the voltage divider formula, or even a 5K or 10K potentiometer. The only other components we will need are 3 pull-down resistors. Resistors with values 10K, 20K and 47K are commonly used, but any reasonably high value resistor will do.

Hardware Setup

Arduino Mega reading iGaging stainless steel scales
Arduino Breadboard Setup
  • Arduino 3V3 pin connected to the red wire (all three scale)
  • Arduino GND pin connceted to the black wire (all three scale)
  • Arduino digital pin 2 connected to the white wire through the voltage divider (all three scale)
  • Arduino digital pins 3,4,5 connected to green wire on x, y and z scales respectively

Arduino Sketch

The complete Arduino DRO sketch is available on the project's Downloads page.

First, lets declare some variables and constants (to make the code more readable):

//pin definitions
int const clockPin = 2;
int const xDataPin = 3;
int const yDataPin = 4;
int const zDataPin = 5;


//variables that will store the readout
long xCoord;
long yCoord;
long zCoord;

Next, we need to initialize the pins to the right modes (input or output) inside the setup() function as follows:

//clock pin should be set as output
pinMode(clockPin, OUTPUT);

//data pins should be set as inputs
pinMode(xDataPin, INPUT);
pinMode(yDataPin, INPUT);
pinMode(zDataPin, INPUT);


In the loop() function we will read the first 20 bits in a for loop.

int bitOffset;

//read the first 20 bits
for(bitOffset = 0; bitOffset<20; bitOffset++)
{
//tick
digitalWrite(clockPin, HIGH);

//give the scales a few microseconds to think about it
__asm__("nop\n\t");
__asm__("nop\n\t");
__asm__("nop\n\t");

//tock
digitalWrite(clockPin, LOW);

//read the pin state and shif it into the appropriate variables
xCoord |= (digitalRead(xDataPin)<<bitOffset);
yCoord |= (digitalRead(yDataPin)<<bitOffset);
zCoord |= (digitalRead(zDataPin)<<bitOffset);
}

Please note that lines __asm__("nop\n\t"); simply instruct the process to do nothing for one cycle. They are there to give the scales time to respond to the clock signal.

Finally, the last bit is handled by the following code:

//tick
digitalWrite(clockPin, HIGH);

//give the scales a few microseconds to think about it
__asm__("
nop\n\t");
__asm__("
nop\n\t");
__asm__("
nop\n\t");

//tock
digitalWrite(clockPin, LOW);

//read the last bit (signified the sign)
//if it's high, fill 11 leftmost bits with "1"s


if(digitalRead(xDataPin)==HIGH)
xCoord |= (0x7ff << 21);

if(digitalRead(yDataPin)==HIGH)
yCoord |= (0x7ff << 21);

if(digitalRead(zDataPin)==HIGH)
zCoord |= (0x7ff << 21);

Conclusion

This is all there is to it. As you can see, reading iGaging scales with Arduino is very easy and doesn't require too much hardware. To make a more permanent setup using an Arduino proto shield please take a look at the Arduino DRO DIY Build Instrucions

25 comments :

  1. I'm missing something... why don't we have to cycle the clock a 21st time? seems you're just reading the 20th bit twice?

    ReplyDelete
  2. Oops,
    You're right. I'm fixing it right now.

    Thank you for a good catch.
    Yuriy

    ReplyDelete
  3. Интересный проект - спасибо!
    Большая просьба - вернуть ссылкам подчеркивание. Или цвет...

    ReplyDelete
    Replies
    1. Алексей,
      Спасибо за комлимент :) Цвет и подчеркивание добавил...

      Delete
  4. Can these be overclocked to increase the read frequency?

    ReplyDelete
    Replies
    1. They can, but how fast depend on a particular units. Out of 6 scales, two ran pretty reliably in 1 MHz clock range, and one was flaky at anything above 100 KHz.
      Additionally, these scales have a peculiar habit of resetting randomly, and the frequency appears to be proportional to the serial clock speed (i.e. the faster I drove them, the more likely they were to reset).

      Delete
    2. Good work! I've got a couple of scales I will be testing soon. I have a couple of Q's though. What is the approximate read frequency of your code above, and what is the best way to slow it down? Do you see any issues scaling this up to 30 readouts?

      Delete
    3. Thank you.
      Please take a look at the newer posting: http://www.yuriystoys.com/2012/09/arduino-bluetooth-module-wireless-dro.html. The attached sketch reads the scales about 25 times per second.
      You can slow it down by increasing the delay at the end of the loop function. Adding scales will slow it down as well, since transferring each scales position will take non-trivial time.
      I imagine you can have as many scales as you can connect to Arduino Mega (51 I think, since you need one pin for clock output and two for UART).

      Delete
  5. Hello,

    I dont understand the concept.
    I have a scale which provides the clock.
    Do you have a special scale which works with external clock?
    If i try to "override" the internal scale-clock my DSO shows an unusable mixture of both clocks.

    ReplyDelete
    Replies
    1. Correct, these scales don't provide their own clock. The "remove display" unit the come with provides the clock. Since I'm not using the display that came with the scales, I had to provide the externa clock.

      Thank you
      Yuriy

      P.S. Shumatech has a very detailed writeup here: http://www.shumatech.com/web/21bit_protocol

      Delete
  6. Hello Yuriy,
    I have a problem with one "excersise" in my university. We have this measure tool "iGaging Woodworking Digital Scales and Readouts" (http://www.igaging.com/page18.html) and i want to read measurements in a Windows based PC and not from it's own "remove display". Can you help me figure this out???

    Thanks.

    ReplyDelete
    Replies
    1. Hello,
      You can't plug them into the PC directly. You can use the Arduino code (link above), connect it to the PC via USB and then read the stream from the serial port.
      Take a look at my latest post. It explains what the protocol is etc. I'll try to post some example code later on how to do it in C#.
      Thank you
      Yuriy

      Delete
    2. Thank you for your answer Yuriy. Now i want to know that: I follow the insructions you write in your post for arduino?? I mean do i need all the tools you write (resistors, voltage divider etc)? The connections will be the same? In my example do i have one or three scales and if i have one how the connections are? At last the code you post fits my measurement tool?

      Thank you and sorry for my bad english.

      Delete
    3. Ok Yuriy. I understand that i have only one scale (X), (i don't need the other two) and i have made the "hardware job" so i connect the arduino to my pc via USB. What about the software? I think that if i delete the lines in your code which is about Y and Z scales the code is ok or am i wrong? So, if it's ok can you help me with the DRO interface like the one you did for anroid devices?

      Delete
  7. Hi
    I was looking for infos on the igaging scales i recently ordered and how to build an DRO for it - seems i can use my time for other things than creating my own DRO but instead just use yours! Great site and projects!
    ps: looking forewad to see somewhen an arduione based solution for glass scales

    ReplyDelete
  8. If I reset my MCU while reading the data from the scales, how do I make sure I get the correct info after the reset?

    ReplyDelete
    Replies
    1. So if the reading got interrupted after reading fe. the 4th bit, I want to start reading from the 1st bit again instead of continuing from the 5th bit.
      Does the scales have some kind of timeout or do I need to disable the power source of the scales and enable it again if I forget (MCU reset) which bit of the data I was reading?

      Delete
    2. Cyberbeni,
      You know, this is an excellent question.
      From what I can see the scales have a timeout. In fact if your refresh rate is too fast they start glitching like mad. IIRC, I had to have around 25-40 millisecond interval between the reads. If I get some time this weekend I'll try to set up a more formal experiment.

      Thank you
      Yuriy

      Delete
  9. Is the ANdroid DRO compatible with the serial output of the new igaging "ABSOLUTE" series ? : http://www.igagingstore.com/38-Absolute-Digital-Readout-DRO-Stainless-Steel-S-p/205483.htm

    ReplyDelete
    Replies
    1. I don't know; haven't had a chance to play with the new model.

      Delete
    2. Short answer: no.

      At a minimum, the Absolute DRO has a 2KHz clock. But, changing the clock freq isn't enough.

      The data line is severely attenuated with a 5.6K PD resistor. The original display unit has a 100K PU resistor, so this will require a schematic change to match.

      Have not had a chance to look at the data on the logic analyzer to confirm if it is still 21-bit.

      (There also appears to be a pull up on pin 4 of the Mini-USB. Looks to be a basic connection check - the control unit stops sending the clock if that pull up is removed. Looks like this can be ignored.)

      Will investigate further and post an update as time permits.

      Delete
    3. Nathan,
      Thank you for the information.
      Yuriy

      Delete
  10. Здравствуйте Юрий! Подскажите пожалуйста в чем может быть проблема. Я загрузил Ваш скетч(v2.2) в ардуино и на c# считываю данные с COM порта, Данные считываются нормально но иногда сбиваются. И если быстро поперемещать линейку то тоже сбивается. Подскажите пожалуйста в чем может быть дело? Заранее благодарен!

    ReplyDelete
    Replies
    1. Олег,
      Может быть много причин. Для начала я бы повесил кандёр (0.1 uF например) между питанием и землёй. Можно также замедлить частоту считывания. На глючных линейках ето иногда помогает.
      Эсли вы ещё не читали, посмотрите пожалуйста на секцию "Troubleshooting" внизу вот етой страницы: http://www.yuriystoys.com/p/arduino-basic-dro-controller.html
      Если не поможет, пишите мне на мыло: ycroosh at gmail dot com, попробую помочь...
      С ув.
      Юра

      Delete

Except where otherwise noted, this work is licensed under
Creative Commons Attribution-ShareAlike 3.0 Unported License.
Creative Commons License