Digitális tolómérő külső kijelző

Processing/Wiring (illetve C) nyelvű programozási fogások, tippek. (AVR-Duino, Arduino, EthDuino, Diecimila, Severino, Nano, LilyPad)
László
DrótVégénSzéndarab
Hozzászólások: 17
Csatlakozott: 2015. április 6. hétfő, 10:32

Digitális tolómérő külső kijelző

Hozzászólás Szerző: László »

Üdv Mindenkinek!

Az esztergámhoz szeretnék digitális kijelzőt csinálni Arduino Uno-val.
Idáig ott artok, hogy ki tudom írni egy tolómérő jeleit LCD-re. Itt meg állt a tudományom. A program magját a neten találtam.
Itt:https://sites.google.com/site/marthalpr ... al-caliper

Kód: Egész kijelölése

int i;

int sign;

long value;

float result;

int clockpin = 4;  

int datapin = 5;

unsigned long tempmicros;

 

 

void setup() {

  Serial.begin(9600);

  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;    

  Serial.println(result,2); //print result with 2 decimals

  delay(1000);

}
Négy napja próbálkozom,de sehogy sem sikerül.
Az egyik próba két tolómérőre:

Kód: Egész kijelölése

int i;

int n;

int sign;

int sign1;

long value;

long value1;

float result;

float result1;

int clockpin = 2;  

int datapin = 3;

int clockpin1 = 4;  

int datapin1 = 5;


unsigned long tempmicros;

 

 

void setup() {

  Serial.begin(9600);

  pinMode(clockpin, INPUT);

  pinMode(datapin, INPUT);
  
  pinMode(clockpin1, INPUT);

  pinMode(datapin1, 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

     }
  while (digitalRead(clockpin1)==HIGH) {} //if clock is LOW wait until it turns to HIGH

  tempmicros=micros();

  while (digitalRead(clockpin1)==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;

      }

    }
    
   } 
  sign1=1;

  value1=0;

  for (n=0;n<23;n++) {

    while (digitalRead(clockpin1)==HIGH) { } //wait until clock returns to HIGH- the first bit is not needed

    while (digitalRead(clockpin1)==LOW) {} //wait until clock returns to LOW

    if (digitalRead(datapin1)==LOW) {

      if (i<20) {

        value1|= 1<<n;

      }

      if (n==20) {

        sign1=-1;

      }

    }

  }

  result=(value*sign)/100.00;    
  result1=(value1*sign1)/100.00;   

  Serial.print(result,2); //print result with 2 decimals
  Serial.print("     ");
  Serial.println(result1,2); //print result with 2 decimals

  delay(100);

}
Sajnos nem működik.
Tudna valaki segíteni abban, hogyan lehet ezt a részt úgy átalakítani, hogy 3 tolómérőt dekódoljon.
Előre is köszönöm.
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Re: Digitális tolómérő külső kijelző

Hozzászólás Szerző: Robert »

Először az egyik, majd a másik tolomerod probald dekodolni.

Azonban a program elején a várakozást azt mondja meg, hogy vársz addig, amíg meg nem mozdítják a tolómérőt.
Mozdítás után dekódoja a számot.

Ami neked kell:
INT alapon nézed, hogy melyik tolómérőt mozgatták. Ha mindhármat/kettőt - döntened kell melyik adatát dolgozod fel (csak az egyiket).
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Re: Digitális tolómérő külső kijelző

Hozzászólás Szerző: kapu48 »

//Egy elképzelés. Egyszerre figyeljük mind a 3 clock jelet:
// 3db. tolómérö figyelésre

Kód: Egész kijelölése

int i;

int sign;

long value;

float result;
// 8 bites port figyelésére, elég a 8 bites regiszter!
const byte clockpin1 = 2;  
const byte clockpin2 = 3;
const byte clockpin3 = 4;

byte clockNum = 0;

const byte datapin1 = 5;
const byte datapin2 = 6;
const byte datapin3 = 7;


unsigned long tempmicros;

 

 

void setup() {

  Serial.begin(9600);

  pinMode(clockpin1, INPUT);
  pinMode(clockpin2, INPUT);
  pinMode(clockpin3, INPUT);
  
  pinMode(datapin1, INPUT);
  pinMode(datapin2, INPUT);
  pinMode(datapin3, INPUT);
  
}



 void loop () {
  clockNum = 0;
  while (clockNum == 0) { // egyszerre figyeljük mind a 3 orajelet
    if(digitalRead(clockpin1)==HIGH) clockNum = clockpin1;
    if(digitalRead(clockpin2)==HIGH) clockNum = clockpin2;
    if(digitalRead(clockpin3)==HIGH) clockNum = clockpin3;
  }     //  if clock is LOW wait until it turns to HIGH

  tempmicros=micros();
  // Ha valamelyik megváltozik? Csak azt figyeljük tovább!
  while (digitalRead(clockNum)==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 megkapja melyik mérö mozog
    decode(clockNum); //decode the bit sequence

  }

}

 
  // Decode megkapja melyik mérö mozog
void decode(byte clockNum_) {

  sign=1;

  value=0;
  byte readPin;
  // Beállitja az aktuállis datta pint
  switch (clockNum_) {
    case clockpin1:
        readPin = datapin1;
      break;
    case clockpin2:
        readPin = datapin2;
      break;
    case clockpin3:
        readPin = datapin3;
      break;
  }
      
  for (i=0;i<23;i++) {
    // Várakozás, amíg az óra visszatér a High az első bit nincs szükség
    while (digitalRead(clockNum_)==HIGH) { } //wait until clock returns to HIGH- the first bit is not needed
    // Várja meg, amíg az óra visszaáll LOW
    while (digitalRead(clockNum_)==LOW) {} //wait until clock returns to LOW
    // Beolvasa az adat pint
    
    if (digitalRead(readPin)==LOW) {

      if (i<20) {

        value|= 1<<i;

      }

      if (i==20) {

        sign=-1;

      }

    }

  }

  result=(value*sign)/100.00; 
  
  Serial.print("Mero azonosit = "); //
  Serial.print(clockNum_); //print result with 2 decimals
  Serial.print("  Mert ertek mm = "); //
  Serial.println(result,2); //print result with 2 decimals

  delay(100);

}
// A hátránya, hogy csak 1 mérő mozoghat 1*-re!
// De azért vagyunk programozók, hogy ezt is meg oldjuk a későbbiekben!
// üdv kapu48!
László
DrótVégénSzéndarab
Hozzászólások: 17
Csatlakozott: 2015. április 6. hétfő, 10:32

Re: Digitális tolómérő külső kijelző

Hozzászólás Szerző: László »

Azt hiszem rosszul kezdtem a segítség kérést. El kellett volna magyarázni mii is csinál a program.
Tehát a tolómérő folyamatosan küldi a jelet.
Minden adat csomag 24 bitből áll.
Az adatok egy adat és egy óra jelből állnak.
A 24 bites csomagok között egy hosszabb szakasz van amikor a CLK (órajel) magas marad.
Ez után az első bit mindig magas, de ennek nincs jelentése (funkciója)
A következő bitek tartalmazzák az értéket 100-al szorozva.
Pl: 1,5 mm a tolómérőn a kódban 150- ként jelenik meg.
A 21. Bit az előjel, Ha Bit 21 HIGH az érték negatív.

Az arduinó kód, figyli a HIGH szintet, ha hosszabb mint 500 micros akkor kezdődik egy új Bitsorozat, amit dekódol.

Ezért gondolom hogy a három tolómérőt egymás után és folyamatosan kell kiolvasni, mivel a jel akkor is jön, ha a tolómérö nem mozog.

Hozzá kezdtem a kód megírásához, de elakadtam.

jelenleg itt tartok:

Kód: Egész kijelölése

int i;
int s;
int sign;
long value;
float result0;
float result1;
int clockpin[] = {4,6,8}; 
int datapin[] = {5,7,9}; 
unsigned long tempmicros;

void setup() {
   Serial.begin(9600);
  for(i=0; i < sizeof(datapin); i++) { 
   
     pinMode(clockpin[i], INPUT); 
   
     pinMode(datapin[i], INPUT);

  } 

}

void loop() {
  
  for(i=0; i < sizeof(datapin); i++) { 
    
  pinMode(clockpin[i], INPUT); 
  pinMode(datapin[i], INPUT); 
}
  
  while (digitalRead(clockpin[i])==HIGH) {} //if clock is LOW wait until it turns to HIGH

  tempmicros=micros();

  while (digitalRead(clockpin[i])==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 (s=0;s<23;s++) {

    while (digitalRead(clockpin[i])==HIGH) { } //wait until clock returns to HIGH- the first bit is not needed

    while (digitalRead(clockpin[i])==LOW) {} //wait until clock returns to LOW

    if (digitalRead(datapin[i])==LOW) {

      if (i<20) {

        value|= 1<<i;

      }

      if (i==20) {

        sign=-1;

      }

    }

  }

  result0=(value*sign)/100.00;   
  result1=(value*sign)/100.00;   

  Serial.print(result0,2);
  Serial.println(result1,2); 
  delay(1000);

}
A void decode() utáni rész amit nem tudum, hogyan folytassam
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Re: Digitális tolómérő külső kijelző

Hozzászólás Szerző: kapu48 »

Akkor mindkettönk megoldása tök rossz!
:mrgreen:

3 külön szálon kellene figyelni, a 3 különböző clock jelet!
De akkor egyáltalán nem lehetnek benne várakozások!
A " while (digitalRead(clockpin)==HIGH) {} " időzítések itt abszolut rosszak!

Írsz minden toloméröre külön decode rutint! És a loop-bol egymásután meghívod öket.
László
DrótVégénSzéndarab
Hozzászólások: 17
Csatlakozott: 2015. április 6. hétfő, 10:32

Re: Digitális tolómérő külső kijelző

Hozzászólás Szerző: László »

Úgy látom egyhamar nem lesz kijelzőm. Hol lehet megtalálni a dacode parancs leírását. A neten nem találok semmit róla.
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Re: Digitális tolómérő külső kijelző

Hozzászólás Szerző: kapu48 »

Ezt használod a programodban!!

void decode() {
....

Az eredeti rutint használd! Ne az általad elrontottat!

Irsz belölle 3 példányt, a 3 toloméröre ki osztott pinekkel.
Bele rakod az loop-ban levő indítási várakozást is.

És egymás után meghiva, egymás után beolvasod a 3 tolomérő értékeket!

Szerintem így is olyan gyors lessz, hogy szemmel nem tudod érzékelni a késést!

A Delay(1000)-et vedki belölle!
László
DrótVégénSzéndarab
Hozzászólások: 17
Csatlakozott: 2015. április 6. hétfő, 10:32

Re: Digitális tolómérő külső kijelző

Hozzászólás Szerző: László »

Kössz, holnap ez lesz a délutáni program. :-)
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Re: Digitális tolómérő külső kijelző

Hozzászólás Szerző: kapu48 »

Igy képzelem:

Kód: Egész kijelölése

//Egy elképzelés. Egyszerre figyeljük mind a 3 clock jelet:
// 3db. tolómérö figyelésre

int i;

int sign;

long value;

float result;
// 8 bites port figyelésére, elég a 8 bites regiszter!
byte clockpin1 = 2;  
byte clockpin2 = 3;
byte clockpin3 = 4;

byte clockNum = 0;

byte datapin1 = 5;
byte datapin2 = 6;
byte datapin3 = 7;


unsigned long tempmicros;

 

 

void setup() {

  Serial.begin(9600);

  pinMode(clockpin1, INPUT);
  pinMode(clockpin2, INPUT);
  pinMode(clockpin3, INPUT);
  
  pinMode(datapin1, INPUT);
  pinMode(datapin2, INPUT);
  pinMode(datapin3, INPUT);
  
}



 void loop () {
  decode1();
  decode2();
  decode3();

}

 
void decode1() {

  sign=1;

  value=0;

Wait_1:
    while (digitalRead(clockpin1)==HIGH) {} //if clock is LOW wait until it turns to HIGH
    

  tempmicros=micros();

  while (digitalRead(clockpin1)==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

  
  for (i=0;i<23;i++) {

    while (digitalRead(clockpin1)==HIGH) { } //wait until clock returns to HIGH- the first bit is not needed

    while (digitalRead(clockpin1)==LOW) {} //wait until clock returns to LOW

    if (digitalRead(datapin1)==LOW) {

      if (i<20) {

        value|= 1<<i;

      }

      if (i==20) {

        sign=-1;

      }

    }

  }

  result=(value*sign)/100.00;    
  Serial.print(" Tolomero 1 = ");
  Serial.println(result,2); //print result with 2 decimals
  }else{  goto Wait_1 ;}
  
  //delay(100);

}

void decode2() {

  
}

void decode3() {

  
}


Neked kel megirnod a részekett :

Kód: Egész kijelölése

void decode2() {

  
}

void decode3() {

  
}
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Re: Digitális tolómérő külső kijelző

Hozzászólás Szerző: kapu48 »

Hali!

Azért jó lenne tudni mire jutottál? Bevált az ötlet? Vagy elakadtál?
László
DrótVégénSzéndarab
Hozzászólások: 17
Csatlakozott: 2015. április 6. hétfő, 10:32

Re: Digitális tolómérő külső kijelző

Hozzászólás Szerző: László »

Köszönöm a segítséget. A hétvégén lesz időm kipróbálni.
László
DrótVégénSzéndarab
Hozzászólások: 17
Csatlakozott: 2015. április 6. hétfő, 10:32

Re: Digitális tolómérő külső kijelző

Hozzászólás Szerző: László »

Nem megy ez nekem, még tanulnom kell. Folyton elakadok. Alapvető dolgokat nem tudok. De nem adom fel, csak gyakorlok. Ha sikerült jelentkezem. Köszönöm a segítséget.
László
DrótVégénSzéndarab
Hozzászólások: 17
Csatlakozott: 2015. április 6. hétfő, 10:32

Re: Digitális tolómérő külső kijelző

Hozzászólás Szerző: László »

Nem gondoltam volna, hogy ilyen hamar sikert érek el. :-)

Két tolómérővel működik.

Így néz ki:

Kód: Egész kijelölése

int i;

int sign;

long value;

float result;

int clockpin1 = 4;  
int clockpin2 = 6;  
int datapin1 = 5;
int datapin2 = 7;

unsigned long tempmicros;

 

 

void setup() {

  Serial.begin(9600);

  pinMode(clockpin1, INPUT);
  pinMode(clockpin2, INPUT);

  pinMode(datapin1, INPUT);
  pinMode(datapin1, INPUT);

}



 void loop () {

  while (digitalRead(clockpin1)==HIGH) {} //if clock is LOW wait until it turns to HIGH

  tempmicros=micros();

  while (digitalRead(clockpin1)==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

    decode1(); //decode the bit sequence

  }
   while (digitalRead(clockpin2)==HIGH) {} //if clock is LOW wait until it turns to HIGH

  tempmicros=micros();

  while (digitalRead(clockpin2)==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

    decode2(); //decode the bit sequence

  }

}

void decode1() {

  sign=1;

  value=0;

  for (i=0;i<23;i++) {

    while (digitalRead(clockpin1)==HIGH) { } //wait until clock returns to HIGH- the first bit is not needed

    while (digitalRead(clockpin1)==LOW) {} //wait until clock returns to LOW

    if (digitalRead(datapin1)==LOW) {

      if (i<20) {

        value|= 1<<i;

      }

      if (i==20) {

        sign=-1;

      }

    }

  }

  result=(value*sign)/100.00;    
  Serial.print("Egyes");
  Serial.println(result,2); //print result with 2 decimals

  delay(1000);

} 

void decode2() {

  sign=1;

  value=0;

  for (i=0;i<23;i++) {

    while (digitalRead(clockpin2)==HIGH) { } //wait until clock returns to HIGH- the first bit is not needed

    while (digitalRead(clockpin2)==LOW) {} //wait until clock returns to LOW

    if (digitalRead(datapin2)==LOW) {

      if (i<20) {

        value|= 1<<i;

      }

      if (i==20) {

        sign=-1;

      }

    }

  }

  result=(value*sign)/100.00;    
  Serial.print("Kettes");
  Serial.println(result,2); //print result with 2 decimals

  delay(1000);

} 
Még egy kis finomítás, tömörítés, LCD kijelző és jöhet a szerelés.
Köszönöm a segítséget.
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Re: Digitális tolómérő külső kijelző

Hozzászólás Szerző: kapu48 »

Ügyes vagy!

A 3.-ís ugyanilyen könnyű lesz!

Csak mindenből +1 3-adik copi-paszta, és átszámozod a használt pineket 3.-ra.


Csak ezt a rondaságot tüntesd el belőle: delay(1000); !!!
Mert lassítja a változás érzékelését!

Inkább old meg, hogy csak akkor írjon az LCD-re ha az újonnan beolvasott érték nem egyezik a régi értékkel.
Avatar
csegebiga
Chipgyilok
Hozzászólások: 288
Csatlakozott: 2015. március 27. péntek, 21:27

Re: Digitális tolómérő külső kijelző

Hozzászólás Szerző: csegebiga »

halihó!
kapu48 mester egy párhzamos topikban javasolta a módszert, de te is tudnád az elvet alkalmazni:
használj intelligens szenzor interfészt!
a legegyszerűbb attiny chipet programozd fel, összesen két funkcióra:
1. fogad 1, azaz egy tolómérőtől érkező értéket, dekódolja, tárolja az aktuális állapotot
2. mikor az uno kérdezi, átküldi az értéket
így kikerülöd atz az időzítési csapdát, mikor egyszerre két mérőd változását kéne dekódolni. kiosztottad az időzítésérzékeny feladatokat külön alrendszerbe, a központ csak az értékeket kapja meg.
a kommunikációra valamilyen soros (iic, spi, rs485, stb) buszrendszerre felfűzhető illesztést javaslok, mert így a rendszer szükség esetén bővíthető új szenzorokkal
Válasz küldése