DRO using Vernier

Hi Guys.

I am stuck on a project that should have been an easy copy code and build it project but unfortunately nothing seems to be going according to plan.

The Idea I had was to fix a digital vernier to one of the axis of a machine we have in the factory so that the operator of the said machine does not have to measure the machine travel with a vernier every time, he simply has to read the DRO.

These projects have been done many times, and there are many codes and videos available, but I just cant get mine to work.

I am using a Arduino Nano and a Cheap Vernier to do this project.

My code is as follows

//Digital caliper code to read the value off of a cheap set of digital calipers
//By Making Stuff Youtube channel https://www.youtube.com/c/makingstuff
//This code is open source and in the public domain.

const byte clockPin = 2;  //attach to clock pin on calipers
const byte dataPin = 3; //attach to data pin on calipers

//Milliseconds to wait until starting a new value
//This can be a different value depending on which flavor caliper you are using.
const int cycleTime = .32; 

unsigned volatile int clockFlag = 0; 

long now = 0;
long lastInterrupt = 0;
long value = 0;

float finalValue = 0;
float previousValue = 0;

int newValue = 0;
int sign = 1;
int currentBit = 1;

void setup() {
  Serial.begin(115200);
 
  pinMode(clockPin, INPUT);  
  pinMode(dataPin, INPUT); 
  
  
  //We have to take the value on the RISING edge instead of FALLING
  //because it is possible that the first bit will be missed and this
  //causes the value to be off by .01mm.
  attachInterrupt(digitalPinToInterrupt(clockPin), clockISR, RISING);
}

void loop() {  
  
  if(newValue) 
  {
   if(finalValue != previousValue) {
     previousValue = finalValue;
     Serial.println(finalValue,2);     
   }
   newValue = 0;
  }
  
 //The ISR Can't handle the arduino command millis()
 //because it uses interrupts to count. The ISR will 
 //set the clockFlag and the clockFlag will trigger 
 //a call the decode routine outside of an ISR.
 if(clockFlag == 1)
 {
  clockFlag = 0;
  decode();
 } 
  
}

void decode(){
   unsigned char dataIn;
   dataIn = digitalRead(dataPin); 
   
   now = millis();
   
   if((now - lastInterrupt) > cycleTime)
   {
     finalValue = (value * sign) / 100.00;
     currentBit = 0;
     value = 0;
     sign = 1;
     newValue = 1;      
   } 
   else if (currentBit < 16 )
   {
      
     if (dataIn == 0)
     {
       if (currentBit < 16) {
          value |= 1 << currentBit;
       }  
       else if (currentBit == 20) {
          sign = -1;
       }
               
     }
     
     currentBit++;
     
   }
   
   lastInterrupt = now;
   
}

void clockISR(){
 clockFlag = 1; 
}

This is a code that I have been getting results from, although the results are not the type I want there is data being seen.

Currently what is happening is the reading on the vernier is steady and according to the vernier position, but the reading on the DRO jump around (mostly between 0,00 - 2,00 mmand sometimes +-300ish)

I used the instructions as per making stuff website (Digital Calipers)

But my results are bad..

Any advice guys?

The following is the code that I would like to end up using for the DRO (Will be basic with a zero button and LCD Display.. This code also has no response, literally does nothing.

#include <LiquidCrystal.h> 

int i;
int sign;
long value;
float result;
int clockpin = 2;  
int datapin = 3;
unsigned long tempmicros;
//LCD Parameters and Pin allocation
LiquidCrystal LCD(9,8,7,6,5,4);    
 
void setup() {
  Serial.begin(9600);
  LCD.begin(16,2);   
  LCD.setCursor(0,0);                                              //Setsthe LCD Cursor
  LCD.print("   Y-AXIS DRO ");                                        //Prints the quoted text

  LCD.setCursor(0,1);                                              //Setsthe LCD Cursor

  LCD.print("POS: ");

  pinMode(clockpin, INPUT);
  pinMode(datapin, INPUT);
}


 void loop () {
  while (digitalRead(clockpin)==HIGH) {} //if clock is LOW wait until it turns to HIGH
  tempmicros=micros();
  while (digitalRead(clockpin)==LOW) {} //wait for the end of the HIGH pulse
  if ((micros()-tempmicros)>500) { //if the HIGH pulse was longer than 500 micros we are at the start of a new bit sequence
    decode(); //decode the bit sequence
  }
}
 
void decode() {
  sign=1;
  value=0;
  for (i=0;i<23;i++) {
    while (digitalRead(clockpin)==HIGH) { } //wait until clock returns to HIGH- the first bit is not needed
    while (digitalRead(clockpin)==LOW) {} //wait until clock returns to LOW
    if (digitalRead(datapin)==LOW) {
      if (i<20) {
        value|= 1<<i;
      }
      if (i==20) {
        sign=-1;
      }
    }
  }
  result=(value*sign)/100.00;   
   LCD.setCursor(5,1);   
  LCD.print(result,2); //print result with 2 decimals
  LCD.print(" mm");
  LCD.print("                ");
  delay(500);
}

Can you guys point me in the right direction, could it be the vernier? (although vernier works fine)

Can you post a link to the datasheet that explains how the vernier sends data?

...R

You may have a ground problem. Post a complete, hand drawn circuit diagram (not Fritzing).

Here is a Fritzing of the wiring. I also tried earthing the vernier to the arduino (GND of vernier to GND of arduino Nano)
Making Stuff fritz.JPG

Here are some pictures of the datasheet I got with the vernier and the wiring ad vernier I am using. I have tried moving the earth around but no luck?

Also a picture of the results I am getting





jremington:
You may have a ground problem. Post a complete, hand drawn circuit diagram (not Fritzing).

Ill make a hand drawing of the wiring asap, but basically the wiring is as follows:
Arduino is plugged into the Laptop (powered from laptop)
Vernier DATA CLOCK and GND connected to breadboard.
and then connections are as per the image of the fritzing I posted.

This what I thought was going to be a quick and easy project is starting to become a real pain in the behind.. Very annoying, but I guess that's the way it works.

Robin2:
Can you post a link to the datasheet that explains how the vernier sends data?

...R

I have posted a picture of the technical data and the vernier. Maybe I am doing something wrong??

One more thing that I noticed is that even with the vernier off (battery in) there is still data flowing into the arduino???
Only way the data stops is if I remove the earth or remove the battery?

JacquesNel:
I have posted a picture of the technical data and the vernier. Maybe I am doing something wrong??

It's a real PITA having to turn my laptop on its side to read your sideways photo.

In any case neither of the images from the datasheet seem to say anything about connections or communication.

I just noticed in your code in your Original Post that you have the clock as an input. Maybe the Arduino is expected to provide the clock as it has more power available?

if the vernier is providing the clock signal why are you not simply reading the data signal every time the clock goes HIGH?

...R

One of the most terrible problems with Fritzing diagrams (and just one of the reasons why we hate them so much) is that parts aren't labeled.

Which transistors are you using? Do you have them wired correctly (there is no standard for the order of EBC connections)?

Perhaps the source of your problem is calling the digital caliper a "vernier" which it definitely is not. If you Googled "digital caliper serial" you will find all kinds of help on reading the serial data, including using an Arduino.

Seems there are several protocols being used by different manufacturers.

Paul

If you go to this website, there is a wealth of information on digital calipers and DRO's.

Robin2:
It's a real PITA having to turn my laptop on its side to read your sideways photo.

In any case neither of the images from the datasheet seem to say anything about connections or communication.

I just noticed in your code in your Original Post that you have the clock as an input. Maybe the Arduino is expected to provide the clock as it has more power available?

if the vernier is providing the clock signal why are you not simply reading the data signal every time the clock goes HIGH?

...R

To be honest I have very little coding experience and knowledge, The code for this project is a code I found off a website (makingstuff.com) and how to modify the code scares me a bit.

How would a go about getting the to only read the data once the CLOCK goes High?.

Does anyone else have a working code that I can use maybe??

jremington:
One of the most terrible problems with Fritzing diagrams (and just one of the reasons why we hate them so much) is that parts aren't labeled.

Which transistors are you using? Do you have them wired correctly (there is no standard for the order of EBC connections)?

The circuit I used for stepping up the logic level is also from makingstuff.com, see attached picture.

I also used the data sheet for the transistors to make sure of EBC connections.

NPN Transistors.JPG

detown:
If you go to this website, there is a wealth of information on digital calipers and DRO's.
DIY DRO Project | Yuriy's Toys

I will definitely have a look thanks.

How would a go about getting the to only read the data once the CLOCK goes High?.

To understand code, you need to study it very carefully to see what it is ACTUALLY doing and exchange HIGH with LOW as appropriate.

Unfortunately, in the code you posted, many of the key comments are wrong, and state exactly the opposite of what the code is doing. Other bits are simply wrong.

This is a terrible example for a beginner to study, no wonder it doesn't work.

Examples:

 while (digitalRead(clockpin)==HIGH) {} //if clock is LOW wait until it turns to HIGH
  tempmicros=micros();
  while (digitalRead(clockpin)==LOW) {} //wait for the end of the HIGH pulse
   while (digitalRead(clockpin)==HIGH) { } //wait until clock returns to HIGH- the first bit is not needed
    while (digitalRead(clockpin)==LOW) {} //wait until clock returns to LOW

jremington:
To understand code, you need to study it very carefully to see what it is ACTUALLY doing and exchange HIGH with LOW as appropriate.

Unfortunately, in the code you posted, many of the key comments are wrong, and state exactly the opposite of what the code is doing. Other bits are simply wrong.

This is a terrible example for a beginner to study, no wonder it doesn't work.

Examples:

 while (digitalRead(clockpin)==HIGH) {} //if clock is LOW wait until it turns to HIGH

tempmicros=micros();
  while (digitalRead(clockpin)==LOW) {} //wait for the end of the HIGH pulse






while (digitalRead(clockpin)==HIGH) { } //wait until clock returns to HIGH- the first bit is not needed
    while (digitalRead(clockpin)==LOW) {} //wait until clock returns to LOW

Thanks for the reply..

Can you point me in the right direction perhaps? maybe a online tutorial or examples I can learn from?

Sorry, I don't have that sensor and have no interest in trying to figure out how it works.

If you look at the site that I gave you a link to they have a Arduino sketch for a DRO using calipers and displaying it on an Android tablet via bluetooth or usb. It uses an app written by the author of the web page.
Not exactly what you want, but maybe looking at his code would give you a hint as to how it is done.

detown:
If you look at the site that I gave you a link to they have a Arduino sketch for a DRO using calipers and displaying it on an Android tablet via bluetooth or usb. It uses an app written by the author of the web page.
Not exactly what you want, but maybe looking at his code would give you a hint as to how it is done.

Perfect, thanks a ton.