Ik ben al enige jaren in het bezit van een klein draaibankje. Ik vond op internet een beschrijving over het uitlezen van een digitale schuifmaat met behulp van een arduino. Dit bracht mij op het idee om mijn draaibank te voorzien van een digitale uitlezing.

Het bereik van de X-as is beperkt (het is maar een klein draaibankje) en daarom kon hiervoor een gewone digitale schuifmaat worden gebruikt.
Voor de Y as, had ik iets groters nodig en heb ik een HBM meet liniaal gebruikt. Deze was 1 meter lang en heb ik op maat ingekort.

Voor het display heb ik grote (1") 7-segment dsplays gebruikt. De reden hiervoor is, dat als ik aan het draaien ben en mijn ogen gericht heb op het werkstuk, ik vanuit mijn ooghoek toch het display makkeljk kan zien.
Bovendien reageert een led-display snel op veranderende waarden, dat in tegenstelling tot een LCD display.

 

Metaal draaibankje zonder digitale uitlezing.

 

Digitale schuifmaat. Kostte slechts 10 Euro.

Deze gebruik ik voor de X as.
Voor deze toepassing worden de bekken afgezaagd en de dieptemeter verwijderd. Tevens worden het duimwieltje en borgschroef verwijderd.

 

Onder het klepje zitten contacten waar draden aan worden gesoldeerd. De clock en data kan worden ingelezen met een arduino. Op verschillende websites is informatie te vinden over het uitlezen van een digitale schuifmaat bv deze
Om het signaal aan te passen (van 1.5 naar 5 V) dient er een level shifter te worden toegepast.

Elke 160msec word er nieuwe data verstuurt (ongeveer 6 x per seconde). De schuifmaat schakelt zichzelf uit als er gedurende enkele minuten geen beweging heeft plaatsgevonden. Als de arduino gedurende 200 msec geen data meer ontvangt (de schuifmaat is dus uitgeschakeld), dan zet de arduino de schuifmaat weer aan door de on/offknop 300 msec te overbruggen. Hierdoor mis je hoogstens 3 metingen. Dit zal in de praktijk geen probleem zijn want kennelijk gebeurde er toch al niets (anders zou de schuifmaat niet uitschakelen). Er blijven toch nog 4 metingen over.

 

Even passen en proberen wat de beste positie is om de schuifmaat te bevestigen aan de draaibank.

De bekken van de schuifmaat zijn er afgezaagd.

 

De schuifmaat is gemonteerd d.m.v. een stukje aluminium hoeklijn.

De uiteinde van het bewegende deel van de schuifmaat is met een stukje aluminium T-profiel bevestigd aan de dwarsslede.

Het display is afgewerkt met een kunststof kapje.

 

De aluminium hoekprofiel waarop de schuifmaat is aangebracht is gemonteerd aan de schroeven van de schrapers (hieronder zitten viltjes die de geleiding schoon houden).

Het electronica gedeelte blijft op zijn plaats terwijl de liniaal mee beweegt met de dwarsslede.

 

Voor de Y as heb ik een digitale meetliniaal gebruikt van HBM. De lengte heb ik aangepast aan mijn draaibank.

De digitale uitleeseenheid waarin ook de batterijen zijn geplaatst, wordt niet gebruikt.

Ook voor het koppelen van de meet liniaal aan de arduino is een niveauaanppassing noodzakelijk. De liniaal werkt op 3Volt en zal worden gevoed vanuit de arduino.

Er dient door de arduino een clocksignaal te worden gegenereerd waarna de data is uit te lezen.

 

De digitale meetliniaal is aan het bed aan de achterzijde van de draaibank gemonteerd. Het beweegbare deel van de meetliniaal is met een messing plaatje gekoppeld aan de slede.

Ook is te zien hoe de schuifmaat gekoppeld is met de dwarsslede. Het T-vormige uiteinde is het restant van de deels afgezaagde bekken van de schuifmaat.

 

Voor het uitlezen van de schuifmaat en de meetliniaal gebruik ik een arduino pro mini.
Deze is gemonteerd op het printje waar ook de niveau aanpassing word gerealiseerd. De arduino is geplaatst op een 24p ic-voetje en kan zo makelijk los worden gekoppeld indien nodig.

Op dit printje zit ook de spanningsomzetting naar 3.3 volt voor de HBM meetliniaal en 1.5 volt voor de digitale schuifmaat.

 

 
Voor het toetsenbord had ik aanvankelijk dit goedkope matrix keypad in gedachte. Dit werkt wel maar ik vind de bediening niet fijn. Ik wilde wat grotere toetsen die wat makkelijker te bedienen zijn.
 

Uit een oude voip telefoon heb ik de druktoetsen gesloopt. Enkele toetsen hebben een afneembaar transparant dekseltje waaronder je met tekstplaatjes je eigen tekst kunt aanbrengen.

Hier heb ik een opstelling gemaakt met een experimenteer printplaat. Later heb ik hiervoor een printplaat ontworpen en een print ge-etst.

 

Het display is opgebouwd uit 1" 7 -segment displays en worden aangestuurd met een MAX6955.

De MAX6955 is een I2C display driver waarmee 16 7-segment displays kunnen worden aangestuurd.

De printplaat is helaas verkeerd gemaakt. Het sporenpatroon zit aan de verkeerde kant waardoor de componenten met een beetje kunst en vliegwerk er op gesoldeerd zijn.

De printen zijn met hoeklijntjes aan elkaar gekoppeld en kan in zijn geheel in de deksel van het kastje worden gemonteerd

 
Aan de achterzijde van de display print zit ook de arduino gemonteerd.
 

Het digitale meetsysteem geplaatst op de draaibank.

Door op de X of Y toets te drukken kan de meetwaarde op 0 worden gezet of er kan een waarde worden ingevuld.

Bij het invullen van de waarde 888.88 wordt de draairichting omgekeerd. Dit is een instelling die wordt bewaard in de eeprom van de arduino.

 
 

Schema arduino/conversie printje.

Connector rechtsboven ("HBM DRO")
- Data ingang met niveau aanpassing dmv transistor en weerstand.
- Clock uitgang. Deze puls wordt gegenereerd door de arduino waarna de data is uit te lezen (ook weer met niveau aanpassing)
- 3V voedingsspanning voor de meet liniaal. Wordt gemaakt door zenerdiode D2 en weerstand.

Connector rechtsonder ("Schuifmaat").
- Ingang clock en data met niveauaanpassing. Beide signalen komen vanuit de schuifmaat. De clock word gevangen met interrupt 1.
- uitgang on/off overbrugt de aan/uit schakelaar van de schuifmaat indien nodig.
- voedingsspanning 1.4V door spanningsdeler. De schuifmaat verbruikt zeer weinig energie, er loopt dus nauwelijks stroom.

Connector linksboven ("keypad").
- inlezen matrix keypad.

Connector linksonder ("Display").
- t.b.v. aansturen displaydriver MAX6955 met I2C (zie onderstaand schema).


 

Schema display aansturing.

 

// Digitale uitlezing voor draaibank
// maakt gebruik van 1 digitale schuifmaat
// en een digitale meetliniaal HBM
// Arduino versie 1.0.6

#include <Wire.h>
#include <Keypad.h>
#include <EEPROM.h>

#define max1 0x60  //address of max6955 chip
#define X 0        // HBM DRO
#define Y 1        // Schuifmaat
#define factor 2   // meetwaarde schuifmaat. diameter = 1, radius = 2

long zeroPos[] = {0,0};
long inputValue[] = {0,0};
byte richting[] = {1,1};
String lastValue[] = {"",""};
long Coord[] = {0,0};
boolean select[] = {false,false};
boolean block[] = {false,false};
int sign = 1;
long KeypadInput =0;
word Disp[2][8] = {
      {0,0,0,0,0,0,0,0},
      {0,0,0,0,0,0,0,0}
  };

/* ==== schuifmaat variabelen ====*/
volatile byte Y_count=0;                          // counter for reading in bits
volatile byte data[25];                           // array for the 24 data bits (2's complement)
#define Y_ClockPin 3
#define Y_DataPin 4
#define OnOff 5
unsigned long time; // detectie on/off schuifmaat

/* ==== HBM variabelen ====*/
#define X_clockPin 6
#define X_DataPin 7
unsigned long HBMtimer; // HBM timer

/* ==== Keypad variabelen ====*/
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the symbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
  {'7','4','1','.'},
  {'8','5','2','0'},
  {'9','6','3','-'},
  {'C','Y','X','D'}
};
byte rowPins[ROWS] = {17, 15, 11, 10}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {13, 12, 16, 14}; //connect to the column pinouts of the keypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 

boolean keyPressed = false;
unsigned long keypadTimer = 0;
String inputValueString = "";
byte maxInput = 3;

/* ==== Setup MAX6955 ====*/
void MAXSetup() {
  Wire.beginTransmission(max1);
  Wire.write(0x01);       // Start adress  
  Wire.write(0xFF);       // decode all digits 1 is decode 0 gives direct access
  Wire.write(0x01);       // Global intensity default
  Wire.write(0x05);       // Scan limit
  Wire.write(0x61);       // Control register
  Wire.endTransmission();

  Wire.beginTransmission(max1);
  Wire.write(0x07);       // display test
  Wire.write(0x01);       // on
  Wire.endTransmission();
  delay(2000);
  Wire.beginTransmission(max1);
  Wire.write(0x07);       // display test
  Wire.write(0x00);       // off
  Wire.endTransmission();
  dim();                  // aansturen display
}


/* ==== SETUP ====*/   
void setup(){
  pinMode(X_clockPin,  OUTPUT); 
  pinMode(X_DataPin,   INPUT_PULLUP);  
  
  pinMode(Y_DataPin,   INPUT_PULLUP);     // data input on digital pin 4
  pinMode(Y_ClockPin,  INPUT_PULLUP);
  pinMode(OnOff,       OUTPUT);

  richting[X] = memRead(X);            // settings in EEprom
  richting[Y] = memRead(Y);

  Serial.begin(115200);
  Wire.begin(max1);
  MAXSetup();

  delay(500);                             // wait for starting HBM DRO
  for (byte i=0; i <= 5; i++){            // read DRO several times
    HBM_DRO();
    delay(200);
  }
  inputValue[X] = zeroPos[X];             // set zero position
  HBMtimer = 0;

  time = millis();                        // set timer detect On/Off schuifmaat
  Y_count = 0; 
  digitalWrite(OnOff, LOW);
  attachInterrupt(1,clock,FALLING); 
}


/*======== inlezen Schuifmaat ========*/
float Schuifmaat(){
  Coord[Y] = 0;
  for(int i=0; i<14; i++){                    // evalueer bit 1 - 15
     Coord[Y]+= !data[i]<<i;
    }
    if (!data[20]) { Coord[Y] = -1*Coord[Y];} // negatief
    zeroPos[Y] = -1*Coord[Y];                 // verschil t.o.v. 0

    if (richting[Y] == 1){ 
      Coord[Y] += inputValue[Y];
    }
    else {
      Coord[Y] += inputValue[Y];
      Coord[Y] *= -1;
    }
      
  return Coord[Y]*factor;  
}

// interupt routine voor schuifmaat
void clock(){                                 // read in data bits up to 24 total
  if(Y_count<24){
    data[Y_count] = digitalRead(Y_DataPin);
    Y_count++;
  }
} 


/*======== inlezen HBM DRO ========*/
float HBM_DRO(){
  Coord[X] = 0;
  long val = 0;
  for(byte x = 0; x < 21; x++)
  {
   digitalWrite(X_clockPin, LOW);   // output waarde inverted door transistor
   delayMicroseconds(16);
    val = !digitalRead(X_DataPin);  // input waarde inverted door transistor
    Coord[X] += val<<x;
   digitalWrite(X_clockPin, HIGH);
   delayMicroseconds(70);
  }
  
  if(val == 1 ) {                    // laatste bit, 1 = negatief
    Coord[X] |= ((long)0x7ff << 21);
  }
  
  zeroPos[X] = -1*Coord[X];          // plaats waarde in var 0 positie
  Coord[X] += inputValue[X];         // bereken waarde met key input
  return Coord[X]; 
}


void splitIntegerIntoArray(byte XY, int Size, long number) {
    long tempNumber = number;
    for (int i = 0; i <8; i++) { Disp[XY][i] = 0;}
    for (int i = 1; i <= Size; i++) {
        int index = Size - i;
        int digit = tempNumber / pow(10, index);
        Disp[XY][Size-i] = digit;
        tempNumber = tempNumber - pow(10, index) * digit;
    }
}


/*======== Dim dislay in editmode ======*/
void dim(){
  word a;
  word b;
  if (select[X] == true){
    a = 0x00;
    b = 0xFF;
  }
  else if (select[Y] == true) {
    a = 0xFF;
    b = 0x00;
  }
  else {
    a = 0xFF;
    b = 0xFF;
  }

  Wire.beginTransmission(max1);
  Wire.write(0x10); // startadres individuele digit intensiteit
  Wire.write(a);
  Wire.write(a);
  Wire.write(a);
  Wire.write(a);
  Wire.write(b);
  Wire.write(b);
  Wire.write(b);
  Wire.write(b);
  Wire.endTransmission(); 
}



/*======== Aansturen display ==========*/
void display(byte XY, long input){
  long inputAbs = abs(input);
  byte S = 5;
  if (inputAbs < 1000) S = 4;
  if (inputAbs < 100)  S = 3;
  if (inputAbs < 10)   S = 2;
  if (inputAbs < 10)   S = 1;

  splitIntegerIntoArray(XY,S,inputAbs);
  Disp[XY][2] += 128;
  if (input <0) {Disp[XY][4] += 128;} // - teken
  
  Wire.beginTransmission(max1);
  Wire.write(0x20);
  for (int i = 0; i <8; i++) {
    Wire.write(Disp[1][i]);
  }
  for (int i = 0; i <8; i++) {
    Wire.write(Disp[0][i]);
  }
  Wire.endTransmission();  
}

/*===== Convert float to string ===*/
float StrToFloat(String convert) {
  char test_as_char[convert.length()+1];
  convert.toCharArray(test_as_char, convert.length()+1);
  return atof(test_as_char);
}

String NrToString(long input){
  long a = input/100;
  String Value = String(a);
  Value += ".";

  long b = abs( input - (a*100));
  Value += b;
  return Value;  
}

String lastVal(byte XY){
  String tmp = lastValue[XY];
  if (tmp.startsWith("-")) { 
    sign = -1;
    tmp.replace("-", "");
  }
  else { sign = 1; }
  return tmp;
}

String newVal(){
  String tmp = "";
  if (sign == -1) {tmp = "-"; }
  tmp += inputValueString;
  inputValueString = "";
  return tmp;  
}

byte memRead(byte XY){
   return EEPROM.read(XY); 
}

void memWrite(byte XY, byte val){
   EEPROM.write(XY, val);
}

void keerOm(byte XY){
  if (sign == 1){
    richting[XY]=1;
  }
  else {
    richting[XY]=0;
  }
  memWrite(XY,richting[XY]);
  inputValueString = 0;
  sign = 1;  
}


/*=========== Keypad ============*/
void keypad(){
  String voorDeKomma = "";
  String naDeKomma =  "";

  if (!keyPressed){
    String key_ =  String( customKeypad.getKey());
    if (key_ != "") {
     // Serial.println(key_);

      /*=========== X ============*/
      if (key_ == "X") {
        if (block[X] == false) {
          if (select[X] == false) {
            select[X] = true;   // X-as input geselecteerd
            select[Y] = false; 
            block[Y] = true;    // toets Y-as geblokkeerd
            inputValueString = lastVal(X);
          }
          else {
            if (inputValueString == "888.88") {keerOm(X);}
            long tVal = round(StrToFloat(inputValueString)*100);

            // bepaal richting
            if (richting[X] == 1){
               inputValue[X] = zeroPos[X] + (tVal*sign);
             }
            else {
               inputValue[X] = zeroPos[X] - (tVal*sign);
            }

            lastValue[X] = newVal();
            sign = 1;
            maxInput = 3;
            KeypadInput = 0;
            block[Y] = false;
            select[X] = false;
          }
        }
        key_ = "";
      }

      /*=========== Y ============*/
      if (key_ == "Y") {
        if (block[Y] == false) {
          if (select[Y] == false) {
            select[Y] = true;   // Y-as input geselecteerd
            select[X] = false;
            block[X] = true;     // toets X-as geblokkeerd
            inputValueString = lastVal(Y);
          }
          else {
            if (inputValueString == "888.88") {keerOm(Y);}
            long tVal = round(StrToFloat(inputValueString)*100 / factor);

            // bepaal richting
            if (richting[Y] == 1){
               inputValue[Y] = zeroPos[Y] + (tVal*sign);
             }
            else {
               inputValue[Y] = zeroPos[Y] - (tVal*sign);
            }

            lastValue[Y] = newVal();
            sign = 1;
            maxInput = 3;
            KeypadInput = 0;
            block[X] = false;
            select[Y] = false;
          }
        }
        key_ = "";
      }

      /*=========== C ============*/
      if (key_ == "C"){                        // backspace
        byte t = inputValueString.length();
        if (t >0) { t-= 1; }
        if (t == 0) {maxInput = 3;}
        inputValueString = inputValueString.substring(0,t);
        key_ = "";
      }

      /*=========== D ============*/
      if (key_ == "D"){                       // delete input
        inputValueString = "";
        if (select[X] == true) { lastValue[X] = ""; }
        if (select[Y] == true) { lastValue[Y] = ""; }
        sign = 1;
        maxInput = 3;
        key_ = "";
      }

      /*=========== - ============*/
      if (key_ == "-"){
        sign *= -1;
        key_ = "";     
      }

      /*======= 0 - 9 =======*/
      if (key_ != ""){
        if ((inputValueString.length() < maxInput) && (key_ != ".")) { 
          inputValueString += key_;
        }
        if (key_ == ".") {
          inputValueString += key_;
        }
        key_ = "";
      }

      /*=========== Display input waarde ============*/
      if ((select[X]) || (select[Y])){
        int puntPos = inputValueString.indexOf('.'); // bepaal of er een decimale punt aanwezig is

        if (puntPos < 0) {
          voorDeKomma = inputValueString;            // zo niet, voorDeKomma is gehele waarde
        }
        else{                                        // opsplitsen waarden in getal voor en na de komma
          maxInput = puntPos+3;                      // maximaal 3 cijfers voorde komma.
          voorDeKomma = inputValueString.substring(0,puntPos);
          naDeKomma =   inputValueString.substring(puntPos+1,puntPos+3);
          if (naDeKomma.length() == 1) {
            naDeKomma += "0";
          }
        }
        KeypadInput = (voorDeKomma.toInt()*100) + naDeKomma.toInt();   // KeypadInput = waarde voor display    
        KeypadInput = KeypadInput * sign;
      }

      dim();    // Dim display van de niet geselecteerde as waarde
      keyPressed = true;
      keypadTimer = millis();
    } //einde if (key_ != "")
  } //einde if (!keyPressed)

  if (keyPressed){
    if ( (millis() - keypadTimer) > 100){
      keypadTimer = 0;
      keyPressed = false;
    }
  }
}


/*======= Main loop =======*/
void loop(){
  while(Y_count>23){                                // wait until we have all 24 data bits
    detachInterrupt(1);
    digitalWrite(OnOff, LOW);
    
    if (select[Y] == false) { display(Y,Schuifmaat()); } else {display(Y,KeypadInput);}  

    time = millis();                               // set timer On/Off detectie schuifmaat
    attachInterrupt(1,clock,FALLING);              // restart the data-logging
    Y_count = 0;
  } // end while(Y_count>23)
  
  // check of schuifmaat aan staat
  if ((millis() - time) > 200){
    digitalWrite(OnOff, HIGH);                    // zet schuifmaat aan
      if ((millis() - time) > 300){
      digitalWrite(OnOff, LOW);
      time = millis();
    }
  }
  
  if ((millis() - HBMtimer) > 100){
    if (select[X] == false) { display(X,HBM_DRO()); } else {display(X,KeypadInput);}
    HBMtimer =  millis();
  }
  
  keypad();
}
 

Voor vragen click contact