I found this code online and was able to modify it so it will work with my cheap dial indicator. The problem now is the results I am getting are double what they should be. When the dial indicator shows 2mm the serial monitor shows 4mm. I know there is a fix but I can't remember where to make the change. Any help would be greatly appreciated.
#include <Arduino.h>
#define CaliperClocKPin 2
#define CaliperDataPin 3
volatile uint8_t gBitsInPacket;
volatile uint32_t gPacketStart;
volatile uint32_t gValue;
volatile uint32_t gPacketValue;
static uint32_t sPreviousValue;
/*********************************** setup ************************************/
void setup(void)
{
Serial.begin(250000);
pinMode(CaliperClocKPin, INPUT); // Clock pin = 2
pinMode(CaliperDataPin, INPUT); // Data pin = 3
gPacketStart = micros();
sPreviousValue = gPacketValue = 0xBADBADBAD;
gValue = 0;
gBitsInPacket = 0;
attachInterrupt(0, ReadPacketBit, FALLING);
}
/******************************** ReadPacketBit *******************************/
void ReadPacketBit(void)
{
uint8_t data = !digitalRead(CaliperDataPin);
uint32_t now = micros();
uint32_t duration = now - gPacketStart;
/*
* If more than 50ms has passed THEN
* we're at the start of a new packet.
*/
if (duration > 50000)
{
gPacketStart = now;
if (gBitsInPacket == 24)
{
gPacketValue = gValue;
}
gValue = 0;
gBitsInPacket = 0;
}
gValue >>= 1;
gBitsInPacket++;
if (!data)
{
gValue |= 0x00800000;
}
}
char* UInt32ToBinaryStr(
int32_t inValue,
char* inBuffer,
uint32_t inMask = 0x80000000);
/****************************** UInt32ToBinaryStr *****************************/
char* UInt32ToBinaryStr(
int32_t inValue,
char* inBuffer,
uint32_t inMask)
{
uint32_t nMask = inMask;
char* buffPtr = inBuffer;
for (; nMask != 0; nMask >>= 1)
{
*(buffPtr++) = (inValue & nMask) ? '1':'0';
if (nMask & 0xEEEEEEEF)
{
continue;
}
*(buffPtr++) = ' ';
}
*buffPtr = 0;
return(buffPtr);
}
/*********************************** loop *************************************/
void loop(void)
{
uint32_t duration = micros() - gPacketStart;
/*
* Only display the packet content when not actively processing a packet (via Serial).
* If we've passed the end of a packet AND
* the value has changed THEN
* display the packet content
*/
if (duration > 20000 &&
gPacketValue != sPreviousValue)
{
char buffer[50];
char* endBuffPtr = UInt32ToBinaryStr(gPacketValue, buffer, 0x800000); // display the last 6 nibbles
*endBuffPtr = 0;
sPreviousValue = gPacketValue;
bool isMetric = (gPacketValue & 0x800000) == 0;
float packetValue;
uint8_t dPlaces = 2;
if (isMetric)
{
/*
* For metric the value is 100/mm
*/
packetValue = (gPacketValue & 0xFFFFF);
packetValue /= 100;
} else
{
/*
* For inches:
* - the value is 1000/inch
* - bit 0 is for 0.0005, so strip if off
*/
packetValue = ((gPacketValue & 0xFFFFF) >> 1);
packetValue /= 1000;
/*
* If bit 0 THEN
* add 0.0005
*/
if (gPacketValue & 1)
{
dPlaces = 4;
packetValue += 0.0005;
} else
{
dPlaces = 3;
}
}
if (gPacketValue & 0x100000)
{
packetValue = -packetValue;
}
Serial.print(buffer);
Serial.print(" = ");
Serial.print(packetValue, dPlaces);
Serial.println(isMetric ? "mm" : "in");
}
}