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)
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)
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?
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.
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.
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?
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.