NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Support Forum » Carrera Precision CP5906 digital caliper

September 16, 2010
by kle8309
kle8309's Avatar

If anyone knows the protocol for the digital read out please let me know.

September 17, 2010
by hevans
(NerdKits Staff)

hevans's Avatar

Hi kle8309,

It looks like not too many people have worked with the calipers you have, and we certainly have not either. I think your best bet is to try to scope the output of your calipers see if you can figure out what is coming out. Odds are it will be at least very similar to a documented protocol. If you don't have a scope you can try using the MCU itself to detect the signal and then send the data to your PC to visualize. Good luck with this project, keep us updated!

Humberto

September 27, 2010
by kle8309
kle8309's Avatar

// calipers.c // for Caliper DRO with ATmega328p // kle8309 // atmega168

define F_CPU 14745600

include <stdio.h>

include <avr/io.h>

include <avr/interrupt.h>

include <avr/pgmspace.h>

include <inttypes.h>

include "../libnerdkits/delay.h"

include "../libnerdkits/lcd.h"

include "../libnerdkits/uart.h"

uint8_t read(void){

// sample counts of high and low
uint32_t dh=0;
uint32_t dl=0;

// if clock H most likely to be the longest time
// wait it out
while((PINB&(1<<PB2))!=0)
{
    //a++;
    PORTC|=(1<<PC5);

}
// first low get ready
while((PINB&(1<<PB2))==0)
{
    //b++;
    PORTC&=~(1<<PC5);
    PORTC|=(1<<PC3);

}
// first clock high read data now!!!

while((PINB&(1<<PB2))!=0)
{
    //c++;
    PORTC|=(1<<PC5);
    PORTC&=~(1<<PC3);
    if((PINB&(1<<PB1))!=0) {
    dh++;   
    }
    else{
    dl++;
    }
    // if long read break
    if(dh>200||dl>200){
    break;
    }

}

if(dh>dl){
return 1;

}
else{
return 0;
}

}

double digital_read_out(void){

// initialize

uint8_t b_1=0;
uint8_t b_2=0;
uint8_t b_3=0;
uint8_t b_4=0;

uint8_t b_5=0;
uint8_t b_6=0;
uint8_t b_7=0;
uint8_t b_8=0;

uint16_t b_9=0;
uint16_t b_10=0;
uint16_t b_11=0;
uint16_t b_12=0;

uint16_t b_13=0;
uint16_t b_14=0;
uint16_t b_15=0;
uint16_t b_16=0;

uint32_t b_17=0;
uint32_t b_18=0;
uint32_t b_19=0;
uint32_t b_20=0;

uint32_t b_21=0;
uint32_t b_22=0;
uint32_t b_23=0;
//uint32_t b_24=0;

double final=0;
double val=0;

// read bits

b_1=read();
b_2=read();
b_3=read();
b_4=read();

b_5=read();
b_6=read();
b_7=read();
b_8=read();

b_9=read();
b_10=read();
b_11=read();
b_12=read();

b_13=read();
b_14=read();
b_15=read();
b_16=read();

b_17=read();
b_18=read();
b_19=read();
b_20=read();

b_21=read();
b_22=read();
b_23=read();
//b_24=read();

// add accordingly

final=b_1+(b_2<<1)+(b_3<<2)+(b_4<<3)+(b_5<<4)+(b_6<<5)+(b_7<<6)+(b_8<<7)+(b_9<<8)+
          (b_10<<9)+(b_11<<10)+(b_12<<11)+(b_13<<12)+(b_14<<13)+(b_15<<14)+(b_16<<15)+
          (b_17<<16)+(b_18<<17)+(b_19<<18)+(b_20<<19);
//
val=final/100.0;

if(b_21==1){
// handle negative
val=-val;
}

return val;

}

void caliper_power_on() { // SET PINS AS INPUT DDRB |= 0x00; // SET PINS AS OUTPUT DDRC |= 0xff; DDRB |=(1<<PB3); // PULL UP PINS 1 2 3 PORTB|=(1<<PB1)|(1<<PB2)|(1<<PB3);

// turning off and on again will eliminate start up error PORTB&=~(1<<PB3); PORTB|=(1<<PB3);

// Light Indicator PORTC|=(1<<PC0); }

//////////////////////////////MAIN//////////////////////////////////////

int main() {

// start lcd lcd_init(); FILE lcd_stream = FDEV_SETUP_STREAM(lcd_putchar, 0, _FDEV_SETUP_WRITE); lcd_clear_and_home();

// update time uint32_t timeconstant=100; uint32_t n=0;

lcd_clear_and_home(); n=4*timeconstant;

//turn on caliper caliper_power_on();

// skip first dro while(--n>1){ lcd_line_four(); fprintf_P(&lcd_stream, PSTR("Begin in:%5u"),n); delay_us(500); }

//INITIALIZE UNIT BIT uint32_t b_24=0;

while(1){

    // DRO for first 23 bits
    double dro = digital_read_out();

    // reset last read then read 24th 'unit bit'
    b_24=0;
    b_24 = read();

    lcd_line_one();
    fprintf_P(&lcd_stream, PSTR("By Kelvin"));
    lcd_line_two();
    fprintf_P(&lcd_stream, PSTR("Digital Read Out"));
    lcd_line_three();
    fprintf_P(&lcd_stream, PSTR("         "));
    lcd_line_four();
    if(b_24==1){
    // notice the conversion and correction factors
    fprintf_P(&lcd_stream, PSTR("value:%7.3f inches"),(dro*0.0393700787*1.27));
    }
    else{
    fprintf_P(&lcd_stream, PSTR("value:%7.2f mm    "),dro);
    delay_us(500);
    }

}

return 0;

}

September 27, 2010
by kle8309
kle8309's Avatar

This is a modified code for the Carrera Precision CP5906 DRO. I hope this will help others use this particular caliper. Believe it or not, it took my 30 hrs to see this project through.

ps. I tried using comparators but they didn't work too well so I sticked to 4 npn bjt for the non-inverted clock and data level shifting.

September 27, 2010
by kle8309
kle8309's Avatar

PC0 power indicator PC5 Clock indicator PC3 Data indicator PB3 power to caliper PB1 DATA PB2 CLOCK

ps link http://www.youtube.com/watch?v=P-4zTMiHECQ

September 27, 2010
by Ralphxyz
Ralphxyz's Avatar

That's great I just picked up a set of calipers. I haven't any idea of the brand but between your project and the nerdkit caliper project I "should" be able to get something working.

Thank you,

Ralph

September 27, 2010
by kle8309
kle8309's Avatar

Ralph, This thread may be useful to you also http://www.nerdkits.com/forum/thread/683/

Good luck!

October 30, 2010
by kle8309
kle8309's Avatar

code update to calipers project: this one has struct and mem allocation (which requires some mod to the makefile ie. -j .data)

// calipers.c // for Caliper DRO with ATmega328p // Kelvin Le // 10-29-2010

define F_CPU 14745600

include <stdio.h>

include <stdlib.h>

include <avr/io.h>

include <avr/interrupt.h>

include <avr/pgmspace.h>

include <inttypes.h>

include "../libnerdkits/delay.h"

include "../libnerdkits/lcd.h"

include "../libnerdkits/uart.h"

// PC5 is clock led // PC3 is data led // PC0 is power led // PB1 DATA in // PB2 CLK in // PB3 power switch

// these are the data types for data storage // bit 9-16 is 16 bits and 17-24 is 32 bits

struct multi_Arr {
uint8_t b8_array[24]; uint16_t b16_array[8]; uint32_t b32_array[8]; double length;

};

// this is the hard part uint8_t read(void){

// sample counts of high and low
uint32_t dh=0;
uint32_t dl=0;

// if clock H most likely to be the longest time
// wait it out
while((PINB&(1<<PB2))!=0)
{

    PORTC|=(1<<PC5);

}
// first low get ready
while((PINB&(1<<PB2))==0)
{

    PORTC&=~(1<<PC5);
    PORTC|=(1<<PC3);

}
// first clock high read data now!!!

while((PINB&(1<<PB2))!=0)
{
    //c++;
    PORTC|=(1<<PC5);
    PORTC&=~(1<<PC3);
    if((PINB&(1<<PB1))!=0) {
    dh++;   
    }
    else{
    dl++;
    }
    // if long read break
    if(dh>200||dl>200){
    break;
    }

}

if(dh>dl){
return 1;

}
else{
return 0;
}

}

void digital_read_out(struct multi_Arr *DRO){

// init counter
uint8_t i=0;
uint32_t accumulator=0;

// read 24 bits: 1-24 /////////////////////
for(i=0;i<24;i++){
    DRO->b8_array[i] = read(); // index 0-23
    }
// cast 8 bits to uint16: 8-15 // cast 8 bits to uint32: 16-23      
for(i=0;i<8;i++){   
    DRO->b16_array[i] = DRO->b8_array[i+8];
    DRO->b32_array[i] = DRO->b8_array[i+16];
    }

// for the purpose of debugging we will display on slave lcd 
//so we need to shift to the bits
for(i=0;i<8;i++){
    accumulator |= ((DRO->b8_array[i])  << (i+0) );
    accumulator |= ((DRO->b16_array[i]) << (i+8) );
}

for(i=0;i<4;i++){
    accumulator |= ((DRO->b32_array[i])<<(i+16) );
}

DRO->length=accumulator/100.0;
// handle negative
if(DRO->b8_array[20]==1){
    DRO->length = -(DRO->length);
}

// handle unit: if inches
if(DRO->b8_array[23]==1){
    DRO->length = (DRO->length)*0.0393700787*1.27;
}

return;

}

void caliper_power_on() { // SET PINS AS INPUT DDRB |= 0x00; // SET PINS AS OUTPUT DDRC |= 0xff; DDRB |=(1<<PB3); // PULL UP PINS 1 2 3 PORTB|=(1<<PB1)|(1<<PB2)|(1<<PB3);

// turning off and on again will eliminate start up error PORTB&=~(1<<PB3); delay_ms(500); PORTB|=(1<<PB3);

// Light Indicator PORTC|=(1<<PC0); }

//////////////////////////////MAIN//////////////////////////////////////

int main() {

// start lcd lcd_init(); FILE lcd_stream = FDEV_SETUP_STREAM(lcd_putchar, 0, _FDEV_SETUP_WRITE); lcd_clear_and_home();

// update time uint16_t n=300;

//turn on caliper caliper_power_on();

// init DRO structure pointer struct multi_Arr *DRO;

// allocate memory memory using calloc DRO=(struct multi_Arr *)calloc(1,sizeof(struct multi_Arr));

// skip first dro while(--n>1){ lcd_line_four(); fprintf_P(&lcd_stream, PSTR("Begin in:%5u"),n); delay_us(500); } lcd_clear_and_home();

while(1){

    if(DRO==NULL){
        lcd_line_one();
        fprintf_P(&lcd_stream, PSTR("Not enough Mem"));
        delay_ms(200);
    }
    else{       
    // pass dro pointer to function
    digital_read_out(DRO);

    //now dro is stored in dro_mem
    // we print 
    if(DRO->b8_array[23]!=1){
    lcd_line_two();
    fprintf_P(&lcd_stream, PSTR("Length: %7.2f mm"),DRO->length);
    }
    else{
    lcd_line_two();
    fprintf_P(&lcd_stream, PSTR("Length: %7.3f in"),DRO->length);
    }

    }

}

return 0;

}

October 30, 2010
by kle8309
kle8309's Avatar

Later on, I gonna send the 3 bytes of read out using SPI. That is why I used struct to store many different types of readouts.

October 30, 2010
by Ralphxyz
Ralphxyz's Avatar

Just out of curiosity what the heck does

include [HTML_REMOVED]

mean?

Ralph

October 30, 2010
by kle8309
kle8309's Avatar

I don't know, it was like that whenever I upload my code it won't let me do "<>" here are the includes w/o the "<>"

include stdio.h

include stdlib.h

include avr/io.h

include avr/interrupt.h

include avr/pgmspace.h

include inttypes.h

include "../libnerdkits/delay.h"

include "../libnerdkits/lcd.h"

include "../libnerdkits/uart.h"

October 31, 2010
by hevans
(NerdKits Staff)

hevans's Avatar

The forum software removes HTML tags in posts to prevent malicious injection of code in forum posts. To prevent that problem make sure you properly indent all code blocks with at least 4 spaces, which will make sure all > and < are properly escaped. To indent a code block you can just highlight it and and press the Indent Selection as Code Block below the Preview button.

Humberto

November 07, 2010
by kle8309
kle8309's Avatar

My calipers project (SPI and PCINT): http://www.youtube.com/watch?v=HVkW4u-os7c

November 07, 2010
by kle8309
kle8309's Avatar

the link

November 08, 2010
by mrobbins
(NerdKits Staff)

mrobbins's Avatar

Hi Kelvin,

Cool to see it working! Out of curiosity, what are the three different microcontrollers are all doing and what's going on overall?

Mike

November 08, 2010
by kle8309
kle8309's Avatar

So there are three mcu:

  1. Master (upper right):

This mcu is responsible for user interface (I'm currently working on incorporating the ps/2 keyboard program into the current one). When requested, the master will ask slave 1 for calipers DRO. Also, when requested, the master will send an interrupt to slave 2 to update the DRO on slave's memory.

  1. slave 1 (lower left):

constantly acquiring DRO data

  1. slave 2 (lower right):

constantly sending out PWM to drive a linear actuator (not seen in the video). When the master interrupts slave 2, it will calculate a new PWM (time on and time off basically)corresponding to the DRO received.

November 08, 2010
by Ralphxyz
Ralphxyz's Avatar

So will the linear actuator move the measured distance coming from slave 1 DRO data?

What linear actuator are you using?

Ralph

November 11, 2010
by kle8309
kle8309's Avatar

@ Ralph Here is the actuator I'm using: actuator

and yes, I got the actuator to move according to the DRO from the calipers. It is not 100% accurate since the mcu pin output is 4.7V and not the 5V needed (but close). To accommodate for this, I used an external hex inverter (requires a 6.5V Vcc)and shifted the 4.7v to 5v. This is one way to calibrate the actuator. However, this will not a perfect fix since the minimum voltage is 0.2V. Ideally we want 0V, so the actuator will only retract to 2mm and not 0mm.

Right now, I'm working on another algorithm that may self correct itself to the analog position feedback from the acutator (another cool feature about this actuator).

So far, between the calipers and the overall system, I have spent over 70hrs for this project (mostly debugging c codes!).

November 11, 2010
by Ralphxyz
Ralphxyz's Avatar

So you have invested "over" 70hrs and bought a $90.00 actuator so far.

What is your final project? That actuator looks really neat, I want one just to play around with that would be cool.

Ralph

November 11, 2010
by kle8309
kle8309's Avatar

This is part of my senior design "laser light deliver system"

November 14, 2010
by kle8309
kle8309's Avatar

Here is the video with the actuator in it and I also added the ps/2 keyboard:

update

March 12, 2011
by Linkster
Linkster's Avatar

Hi Kelvin,
I also have been working on the DRO project with no luck and more hours than I dare to say. I took a good look at your project and I think I might have the same caliper with the same protocal as you. However, I only have two 2n3904 bjt's and you had mentioned that you used four. could you give me some detail as to how you have these wired? I tried four bjt with the nerdkit code with no luck but your code looks promising. Thanks for the great videos and posts. I enjoy reading your other projects also, I was about to give up completely on mine but I'll give my project one more shot.
Thanks again,
Gary

March 12, 2011
by kle8309
kle8309's Avatar

Hi Gary, First of all, don't give up.

About the calipers project, it would make your life easier if you have access to an oscilloscope and/or multisim. Make sure it's not the chinese protocol (the NK demo) If it's the same protocol as mine then you will have to improvise like I did. You will have to change the NK code to something similar to what I have up above. Note: the Carrera Precision protocol is 24 bits with data set freq of 3.54Hz (much slower than the chinese protocol); clock freq is ~ 1.43Khz

How to wire data/clock level shifter (-> means connection)

  1. unshifted data (or clock)->100kohm->BJT_1 base

  2. 5v source->20kohm->BJT_1 collector and BJT_2 base

  3. BJT_1 and BJT_2 emitters both->GND

  4. MCU I/O pin (pulled high but set as input)->BJT_2 collector (I/O pin: PC4 is for clock input and PC3 is for data input following the code above)

Note: data and clock are amplified using the steps above.

Tips on debugging software

  1. Start with a simple c code (see if you can detect and print out the amplified data/clock output from the calipers)

  2. Use LCD to debug

  3. Use I/O pins and LED to help you debug at checkpoints

let me know if this helps

March 12, 2011
by kle8309
kle8309's Avatar

digital level shifter schematic

March 13, 2011
by Linkster
Linkster's Avatar

Kelvin,
You will have know idea how happy you made me. I knew I needed to run the Data/Clk thru a second BJT but just could not put two and two together. (literally).
I don't even think I could of come close to the code as you did. I had the ND code stripped to bare bones and could only get random numbers. I was pretty much lost without a good scope. Now I can get on with the rest of the project. I just need to write some code to be able to set limits. ie. turn on a relay when a preset measurment is reached.
You are the hero kelvin. Thank you very very much. I'm going to spend some time studing your code and see what I was missing. I'm still learning and finding out an old dog can learn new tricks. (Ain't that right Ralph)?
Thank you again Kelvin.
Gary

March 13, 2011
by kle8309
kle8309's Avatar

// slave1.c

// for Caliper DRO with ATmega168p

// Kelvin Le

// 11-7-2010

define F_CPU 14745600

include <stdio.h>

include <stdlib.h>

include <avr/io.h>

include <avr/interrupt.h>

include <avr/pgmspace.h>

include <inttypes.h>

include "../libnerdkits/delay.h"

include "../libnerdkits/lcd.h"

include "../libnerdkits/uart.h"

include "../libnerdkits/spi.h"

/* PIN DEF

PC5 POWER OUT

PC4 CLK IN PULLED HIGH CALIPERS

PC3 DAT IN PULLED HIGH CALIPERS

PC2 CLK LED OUT

PC1 DAT LED OUT

PC0 DEBUG LED

PB5 SCK IN

PB4 MISO OUT

PB3 MOSI IN

PB2 SS to GND

PB1 INTERRUPT IN ISR(PCINT0_vect) */

// these are the data types for data storage

// bit 9-16 is 16 bits and 17-24 is 32 bits

struct multi_Arr {

uint8_t  b8_array[24];

uint16_t b16_array[8];

uint32_t b32_array[8];

double length;

uint8_t byte_array[3];

};

/-------------------DRO functions-----------------------/

// this is the hard part

uint8_t read(void){

// sample counts of high and low

uint32_t dh=0;

uint32_t dl=0;

// if clock H most likely to be the longest time
// wait it out
while((PINC&(1<<PC4))!=0)
{
    PORTC|=(1<<PC2);

}
// first low get ready
while((PINC&(1<<PC4))==0)
{
    //leds
    PORTC&=~(1<<PC2);
    PORTC|=(1<<PC1);

}
// first clock high read data now!!!

while((PINC&(1<<PC4))!=0)
{
    // leds
    PORTC|=(1<<PC2);
    PORTC&=~(1<<PC1);

    //check data pin
    if((PINC&(1<<PC3))!=0) {
    dh++;   
    }
    else{
    dl++;
    }
    // if long read break
    if(dh>200||dl>200){
    break;
    }

}

if(dh>dl){
return 1;

}
else{
return 0;
}

}

void digital_read_out(struct multi_Arr *DRO){

// init counter
uint8_t i=0;
uint32_t accumulator=0;

// read 24 bits: 1-24 LSB first/////////////////////
for(i=0;i<24;i++){
    DRO->b8_array[i] = read(); // index 0-23
    }
// cast 8 bits to uint16: 8-15 // cast 8 bits to uint32: 16-23      
for(i=0;i<8;i++){   
    DRO->b16_array[i] = DRO->b8_array[i+8];
    DRO->b32_array[i] = DRO->b8_array[i+16];
    }

// for the purpose of debugging we will display on slave lcd 
//so we need to shift to the bits
for(i=0;i<8;i++){
    accumulator |= ((DRO->b8_array[i])  << (i+0) );
    accumulator |= ((DRO->b16_array[i]) << (i+8) );
}

for(i=0;i<4;i++){
    accumulator |= ((DRO->b32_array[i])<<(i+16) );
}

DRO->length=accumulator/100.0;
// handle negative
if(DRO->b8_array[20]==1){
    DRO->length = -(DRO->length);
}

// handle unit: if inches
if(DRO->b8_array[23]==1){
    DRO->length = (DRO->length)*0.0393700787*1.27;
}

return;

}

void caliper_power_on(void) {

// SET PINS AS INPUT

DDRC |= 0x00;

// SET PINS AS OUTPUT

DDRC |= (1<<PC5)|(1<<PC2)|(1<<PC1)|(1<<PC0);

// PULL UP PINS power, clk, and data

PORTC|=(1<<PC5)|(1<<PC4)|(1<<PC3);

// turning power off and on again will reduces start up error

PORTC&=~(1<<PC5); delay_us(500); PORTC|=(1<<PC5);

}

/-------------------------------PACKAGING-----------------------------/

void pack_3_bytes(struct multi_Arr *DRO){

// counter init

uint8_t i=0;

// clear old reading first

for(i=0;i<3;i++) DRO->byte_array[i]=0;

// 3 bytes are packed in byte_array

for(i=0;i<8;i++){
    DRO->byte_array[0] |= ((DRO->b8_array[i+0 ])<<(i));
    DRO->byte_array[1] |= ((DRO->b8_array[i+8 ])<<(i));
    DRO->byte_array[2] |= ((DRO->b8_array[i+16])<<(i));
}

return; }

/--------------------------INTERRUPT HANDLING--------------------------/

/-------------------------------MAIN-----------------------------------/

int main() {

// spi debug led PCO is defined in caliper_power_on()

// start lcd

lcd_init(); FILE lcd_stream = FDEV_SETUP_STREAM(lcd_putchar, 0, _FDEV_SETUP_WRITE); lcd_clear_and_home();
// start master's SPI

// update time uint16_t n=40; uint8_t i=0; uint16_t k=0;

// turn on caliper caliper_power_on();

// init DRO structure pointer struct multi_Arr *DRO;

// allocate memory memory using calloc DRO=(struct multi_Arr *)calloc(1,sizeof(struct multi_Arr));

// skip first dro

while(--n>1){

lcd_line_four();
fprintf_P(&lcd_stream, PSTR("Begin in:%5u"),n);
delay_us(500);
}

// clear lcd

lcd_clear_and_home();

// throw first blank out //SPI_SlaveReceive_char(); while(DRO==NULL){

        lcd_line_one();
        fprintf_P(&lcd_stream, PSTR("Not enough Mem"));
        delay_ms(200);
    }

while(1){

    // pass dro pointer to function
    digital_read_out(DRO);

    //now dro is stored in dro_mem
    // we print 
    if(DRO->b8_array[23]!=1){
    lcd_line_one();
    fprintf_P(&lcd_stream, PSTR("%7.2f mm"),DRO->length);
    }
    else{
    lcd_line_one();
    fprintf_P(&lcd_stream, PSTR("%7.3f in"),DRO->length);
    }

    // if master requests
    if((PINB&(1<<PB1))!=0){
        SPI_SlaveInit();
        // send bytes upon master's request
        if(SPI_SlaveReceive_char()=='m'){
            // pack bytes to send
            pack_3_bytes(DRO);
            // send tag ready
            SPI_SlaveTransmit_char('r');
            // data now packed so we can use SPI to send data
            for(i=0;i<3;i++){
                SPI_SlaveReceive_char(); // just so that this could work
                SPI_SlaveTransmit(DRO->byte_array[i]);
            }       
        }

    }
    else{
        SPI_SlaveOff();
    }
    // slave status
    lcd_line_two();
    fprintf_P(&lcd_stream, PSTR("Slave 1 OK"));
            lcd_line_three();
    fprintf_P(&lcd_stream, PSTR("k: %u"),k++);
}

return 0;

}

March 13, 2011
by kle8309
kle8309's Avatar

Gary, I have noticed that my old c code pin definitions are different from what I described (for data and clock they were PBX but my new code is PCX). So I posted the updated version. Just ignore the SPI and interrupt parts (unless you want to send the DRO to another MCU using SPI). The subroutines that are essential are the read(), digital_read_out(), caliper_power_on(), and main(). Of course, the struct multi_Arr also.
Good Luck!

March 13, 2011
by Linkster
Linkster's Avatar

Kelvin,
I used the code from the very first post. I cuaght the pin listings during the bjt build. I'm still on PB1 & PB2 for Data and Clk. All is working well and I have already wrote the code for the limits and relay. That part is working fine also.
I see in your last post you were able to simplify the initialize and read bits. I'll study this and try it when I understand it. One baby step at a time for me.
If I get daring enough I will also try the slaves with the actuator. but first I need to finish this project. I have to say, I'm impressed with your work and have no doubt that the "laser light deliver system" was a big hit.
Thanks again.
Gary

March 13, 2011
by Linkster
Linkster's Avatar

Kelvin,
Did you happen to run into a problem where the calipers go into sleep mode after 4 minutes and stop transmitting? Usually they will restart if you move the caliper but they won't if they are moved very slowly. For my application, movement or (creep) can be as little as .004" per hour. Just wondering if there is something that can be done to bypass the sleep mode.
Gary

March 13, 2011
by kle8309
kle8309's Avatar

Gary, About the sleep mode, it happens to my calipers too as it try to save power. But i'm not sure how to turn it back on without reseting the DRO which involves reseting the power input.
Here is an idea: Maybe you should try pulling the data to ground/5v whenever it goes to sleep mode because the calipers reactivate whenever there is change in DRO (???)

March 13, 2011
by Linkster
Linkster's Avatar

Tried various combinations with the data/clk pins with no result. I remember seeing the pads for the on/off button. One side was I beleive + and the other side was the activate lead. I know it dosen't lose position during sleep and reactivation so I'm thinking of running another wire from the activation lead to a bjt voltage divider for +1.5 from a MCU PCx. Then write some code to pulse the PCx off and then on every 3 minutes to reset the calipers sleep timer. Should be able to pulse off and on fast enough to hardly notice it happened.
I'll give this a try tommorow after work.
Gary

March 14, 2011
by Linkster
Linkster's Avatar

Turns out that the common to the caliper push buttons are ground and the on/off lead is at +1.65 volts open. Pulling this lead to ground turns caliper on and off.
I ran a wire from the on/off button of the caliper and ran some tests. Problem now is figuring out where to put a 3 min timer in the C-code to create a pulse (off) then (on) to reset the sleep timer of the caliper. The pulse will have to occur twice in quick succession in order to turn off the caliper and then back on, wait 3 minutes and repeat. So far, I have a 2n3904 bjt wired from the on/off lead of the caliper to the Collector. Emitter to ground and Base to PC2 of the MCU. I can toggle off and on but I'm pretty much stuck on code and placement along with using a timer.
More reading required. Anyone care to point in a direction?
Gary

March 27, 2011
by Linkster
Linkster's Avatar

Kelvin,
I'm working on the inches to millimeter portion of the code.

    lcd_line_four();
    if(b_24==1){
    // notice the conversion and correction factors
    fprintf_P(&lcd_stream, PSTR("value:%7.3f inches"),(dro*0.0393700787*1.27));
    }
    else{
    fprintf_P(&lcd_stream, PSTR("value:%7.2f mm    "),dro);
    delay_us(500);
    }

The dro always displays inches even after pushing the mm button on the caliper. The caliper normally defualts to mm on start up and the readout is not acurate unless you display the inches on the caliper.
Was this a problem that you incounterd with the first code? If so, were you able to correct it. I have more time than I dare to say working this part out.
I did solve the sleep timer problem but had to add a wire to the on/off pad of the caliper and trigger it with a timer. The project will be complete once I get the mm to inches working. Is bit 24 (b_24) what makes the change? I see it change when the 4th right digit displays 5 .
Gary

March 27, 2011
by kle8309
kle8309's Avatar

Gary, I didn't not encounter the issue you are having. About the 24th bit. It should be high if you are in inches mode.
Make sure you are reading the 24th bit and not any other bits.

The inches mode should be the one that needs calibration (notice the *1.27 in the code) In mm mode, all you have to do is divide the value by 100.

March 27, 2011
by Linkster
Linkster's Avatar

so, if inches is (b_24==1); then is millimeters (b_24!=1); ?
I can display inches on the NK's LCD and it is the same as the display on the caliper but when I push the mm/inch button on the caliper to go to millimeters the NK,s LCD is apperantly still reading the ("value:%7.3f inches") but displaying about 20 times less than the calipers display when it is in millimeters. If I change to (b_24!=1) then the oppisite happens where ("value%7.2f mm") is displayed on the NK,s LCD and is accurate with the caliper but pushing the mm/inch button to go to inches the NK's LCD stays the same but with a inacurate reading.
In stead of saying all this I could of just said that the (if) statement is not jumping to the (else) statement.
It could also be that my caliper is not exactly the same as yours. I do not have a scope to read the calipers but is there a bit that controls the mm/in display on the caliper itself?
Gary

March 27, 2011
by kle8309
kle8309's Avatar

The 24th bit is the "unit bit". It tells you whether the data should be interpret as inches or mm. High means inches Low means mm

Q:"so, if inches is (b_24==1); then is millimeters (b_24!=1); ?" A:Yes

I think there is some discrepancy with the if and else statement. Use an LED to help you see where the code is.

March 30, 2011
by Linkster
Linkster's Avatar

Kelvin,
I think my caliper may be slightly different than yours in the respect of the 24th bit. With the caliper in mm or inches, the bit changes from high to low while moving through the scale. I do see an association between bit 24 and the half digit (small 5) on the right side of the caliper display. For now, I set the code to display inches on the NK LCD when the caliper is in mm mode since this is the defualt start up for the caliper. This works for me for now. I need to move forward with the rest of the project and once I have things cuaght up I'll come back to the bit 24 problem. I'll look for a nother caliper like yours in the mean time.
Gary

March 30, 2011
by kle8309
kle8309's Avatar

I bought mine calipers on amazon for $20 amazon link

Post a Reply

Please log in to post a reply.

Did you know that microcontrollers have two different kinds of memory, program space (flash) and SRAM? Learn more...