Reading Digital caliper with Arduino
(03-29-2015, 02:49 PM)chucketn Wrote: All I get is Ready: on serial monitor after that change.

Chuck

Chuck,

Did you miss the part where I said "That didn't fix the display issues. There were a number of things I had to change to make it display the data."

Here's the code in its entirety including the formatting of the output to the serial monitor.

Remember you have to change the pins you're using for the clock and data lines. They should be as follows, which is different from what you originally had.

Clock: digital pin 2, connector pin 3.
Data: digital pin 3, connector pin 4.

Ed

Code:
// Do not remove the include below
#include <util/atomic.h>

#define INTERRUPT_NUMBER 0
#define CLOCK_PIN 2                              // The pin associated with the clock pulse
#define CLOCK_TRANSITION FALLING                 // What will happen on the clock pulse that will want us to read the data pin
#define CLOCK_TERMINATION INPUT_PULLUP           // What kind of termination do we want on the clock pin

#define DATA_PIN 3                               // The pin associated with the data
#define DATA_TERMINATION INPUT_PULLUP            // What kind of termination do we want on the data pin
#define DATA_STATE_INDICATING_A_ONE HIGH          // Does a HIGH or LOW on the data line indicate a value of 1

#define CLOCK_NOISE_FILTER 10                   // How many microseconds long must the clock be stable for it to be consider 'good'
#define MINIMUM_BURST_START_PULSE_WIDTH 80000    // At a minimum, how many microseconds long is the pulse at the beginning of a burst
#define MAXIMUM_TIME_FOR_A_SINGLE_BURST 10000    // The maximum amount of time that a burst should take before considered invalid

#define DATA_BIT_ZERO_VALUE 0UL                  // For readability ...
#define DATA_BIT_ONE_VALUE 1UL                   // For readability ...

#define DATA_BITS_IN_A_VALID_BURST 24            // The number of data bits that are expected in a complete burst of data
volatile boolean initialized = false;            // Lets the interrupt get set up right after application start up
volatile boolean processingBurst = false;        // Does the interrupt think it is processing a burst
volatile byte dataBitsReceived = 0;              // Data bit counter used by the interrupt routine
volatile unsigned long lastGoodClockTime = 0;    // The last time the interrupt saw what it thought was a valid clock pulse
volatile unsigned long burstStartTime = 0;       // The time when the interrupt thought the burst started
volatile unsigned long inProcessBurstData = 0;   // The burst of data as it is being captured by the interrupt routine

volatile unsigned long capturedBurstData = 0;    // A complete and validated burst of data
volatile byte capturedBurstCounter = 0;          // A rolling counter of the number of complete bursts we have seen. It must be a byte so increments will be atomic.

// This looks like a lot of code for an interrupt but the if statements should ensure that
// only a small portion of it actually runs during any given interrupt

void clockTransitioned()
{
unsigned long timeAtInterupt = micros();
unsigned long intervalSinceLastInterrupt = timeAtInterupt - lastGoodClockTime;

// If we do not have our ducks in a row so we will get organized

if (!initialized)
{
lastGoodClockTime = timeAtInterupt;
processingBurst = false;
initialized = true;
}

// Is the interrupt because of noise?
else if (intervalSinceLastInterrupt < CLOCK_NOISE_FILTER)
{
/*
Note that we are going to do absolutely nothing in this case, not even update the last valid clock time.
We are really waiting for a transition that is at least CLOCK_NOISE_FILTER later than the
last transition that we thought was good.
*/
}

// Is the interrupt because of a 'beginning of burst' pulse?
else if (intervalSinceLastInterrupt > MINIMUM_BURST_START_PULSE_WIDTH)
{
if (!processingBurst)
{
lastGoodClockTime = timeAtInterupt;
burstStartTime = timeAtInterupt;
(digitalRead(DATA_PIN) == DATA_STATE_INDICATING_A_ONE) ? (inProcessBurstData = DATA_BIT_ONE_VALUE) : (inProcessBurstData = DATA_BIT_ZERO_VALUE);      
dataBitsReceived = 1;
processingBurst = true;
}

// OK, we were in the process of receiving a burst but just got another 'beginning of burst' pulse.
// We'll need to do something here but I will have to figure out exactly what after another cup of coffee.
else
{

}
}

// OK, we are here because we are initialized and we do not think it is noise or a 'beginning of burst' pulse.
// Let see if we believe it is a valid data bit.
else
{
// If we are not in the process of reading a burst then we have a problem and need more coffee
if (!processingBurst)
{

}

// If it has taken longer than we thought is should to show up then we have a problem ... see the coffe issue mentined earlier
else if ((timeAtInterupt - burstStartTime) > MAXIMUM_TIME_FOR_A_SINGLE_BURST)
{

}

// We seem to be at the right place at the right time so grab what ever is on the data line.
else
{
lastGoodClockTime = timeAtInterupt;
inProcessBurstData = inProcessBurstData << 1;               // Make room for the next data bit and then set it

if (digitalRead(DATA_PIN) == DATA_STATE_INDICATING_A_ONE) // We only need to do something if the data line indicates a ONE as the shift has already put in the ZERO value
{
bitSet(inProcessBurstData, 0);
}

                                       else
bitClear(inProcessBurstData, 0);

dataBitsReceived += 1;

if (dataBitsReceived == DATA_BITS_IN_A_VALID_BURST) // Are we done with this burst?
{
capturedBurstData = inProcessBurstData;
capturedBurstCounter = 24;
processingBurst = false;
}
}
}
}

// Variables used by the application loop
unsigned long burstData = 0;
unsigned long tempData = 0;
byte bitCount = 0;

//The setup function is called once at startup of the sketch
void setup() {
// Pin Set Up
pinMode(DATA_PIN, INPUT_PULLUP);
pinMode(CLOCK_PIN, INPUT_PULLUP);

attachInterrupt(INTERRUPT_NUMBER, clockTransitioned, CLOCK_TRANSITION);

Serial.begin(115200);
Serial.println("Ready: ");}

// The loop function is called in an endless loop
void loop()

  {
if (capturedBurstCounter == 24)                          // If there is something new available then get it and print it
{
                         
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)               // Needs to be marked as atomic so the interrupt does not mess with it while we get a local copy of it
{                        
burstData = ~capturedBurstData;
bitCount = capturedBurstCounter;
capturedBurstCounter = 0;
}

                               burstData &= 0x00ffffff;
                               int y = 0;
                               for(int x = 23; x >= 0; x--)
                                 {
                                     if (bitRead(burstData, x))
                                        bitSet(tempData, y);
                                     else
                                       bitClear(tempData, y);
                                       
                                     ++y;
                                 }
               
Serial.print(bitCount);
Serial.print(", ");
Serial.print(tempData, HEX);
Serial.print(", ");
Serial.println(tempData, BIN);
}
}
Reply
Thanks given by:
Same result with new code... Just Ready: on serial monitor...

I think I have a new unused Pittsburgh 6" still in the original case out in the shop. I'll bring it in and let it acclimate overnight, and install a new battery, and try again in the morning.

Chuck
Micromark 7x14 Lathe, X2 Mill , old Green 4x6 bandsaw
The difficult takes me a while, the impossible takes a little longer.
Reply
Thanks given by:
(03-29-2015, 05:19 PM)chucketn Wrote: Same result with new code... Just Ready: on serial monitor...

I think I have a new unused Pittsburgh 6" still in the original case out in the shop. I'll bring it in and let it acclimate overnight, and install a new battery, and try again in the morning.

Chuck

Chuck,

Did you change the wires for the clock and data as I described in my prior message?
Make sure the caliper it turned on prior to activating the serial monitor. The serial monitor will do nothing if you turn the caliper on after starting the serial monitor.

Ed
Reply
Thanks given by:
Yup, tried that. Just Ready:.

Chuck
Edit: Does metric or inch mode make a difference?
Micromark 7x14 Lathe, X2 Mill , old Green 4x6 bandsaw
The difficult takes me a while, the impossible takes a little longer.
Reply
Thanks given by:
(03-29-2015, 06:13 PM)chucketn Wrote: Yup, tried that. Just Ready:.

Chuck
Edit: Does metric or inch mode make a difference?

No, you'll just get different readings.

PM me your mailing address and I'll send you the interface I made.

Ed
Reply
Thanks given by:
Ed, I have a lot of components, including some perf prototyping boards. Can you post a schematic of your interface? I can probably build it myself. PM sent.

Chuck
Micromark 7x14 Lathe, X2 Mill , old Green 4x6 bandsaw
The difficult takes me a while, the impossible takes a little longer.
Reply
Thanks given by:
Here you go Chuck.

Ed

EDIT: added updated schematic.


.pdf   digital caliper interface 03.pdf (Size: 208.42 KB / Downloads: 16)
Reply
Thanks given by:
Chuck,

Delete the revision 02 schematic I posted. I made a correction to the schematic and attached it as revision 03.

The connector numbers are the actual pin numbers of the connector, not the Arduino numbers silk screened on the printed circuit board.

Ed
Reply
Thanks given by:
Chuck,

Are you going to build the interface board or do you want me to send you mine?

Ed

         

   
Reply
Thanks given by:
If you don't mind, go ahead and send me one. I've been under the weather the last couple of days, and have a couple Dr's appts to find out what's up.

Chuck
Micromark 7x14 Lathe, X2 Mill , old Green 4x6 bandsaw
The difficult takes me a while, the impossible takes a little longer.
Reply
Thanks given by:




Users browsing this thread: 12 Guest(s)