Nokkenas meetmachine (camdoctor)

Projecten die niet passen in bovenstaande onderwerpen
Berichten: 3
Geregistreerd: 13 Dec 2017, 22:50

Nokkenas meetmachine (camdoctor)

Berichtdoor Dan Gouweloos » 12 Feb 2023, 12:34

Hallo forumleden,

Ik ben voornemens een nokkenas meetmachine te bouwen en wil kijken of dat lukt met een arduino , echter ik snap van deze programmering niets ,de bedoeling is om een nokkenas van een (auto) motor na te meten in een testopstelling dmv. een aandrijving door een stappenmotor en de meetstappen te initieren door een ttl encoder en de nok gedurende deze beweging te volgen met hetzij een schuifpotmeter of een digitale lineaal .
De spullen die ik heb: nema 23 stappenmotor sl 2690a stepperdriver ,atek ltr 25 meet potentiometer ,en diverse digitale linealen.en een 1024puls/360 ttl encoder van Heidenhain
het liefst zou ik de data gelijk naar een pc willen streamen om daar te analyseren en als dat mogelijk zou zijn via een mooie grafische omgeving aan te sturen.
een meting duurt uiteraard 360 graden maar ik moet ook de nokkenas gecontroleerd kunnen verstellen naar het volgende nokkenpaar ( liefst instelbaar) maar anders vaste waarden 90, 72,60 graden.

Hopend dat iemand mij hiermee kan of wil helpen

met vriendelijke groet Dan Gouweloos

Advertisement

Berichten: 24
Geregistreerd: 20 Jul 2022, 14:40

Re: Nokkenas meetmachine (camdoctor)

Berichtdoor Harm J Seef » 15 Feb 2023, 10:57

Leuk project. Het aansturen van de stappenmotor en het meten van de nokken met een arduino zal het probleem niet zijn. Een schuifpotmeter (is deze wel zuiver lineair?) vraagt om een analoge ingang, en hoewel arduino’s stap 1/1024 is, is dit beslist geen gegarandeerde nauwkeurigheid. Meetlineaal? Kan, maar dan moet je handmatig elke nok in elke hoekstand meten. De nokken kunnen ook met een gebalanceerde wip en pulsboog automatisch digitaal afgelezen worden, wat voor de arduino geen groot probleem moet zijn. Via de seriele monitor kunnen de meetwaarden hoekstand en vectorlengte naar een PC worden gestuurd. Kun je ook de klepsnelheid mee controleren.

De echte moeilijkheid zit eerder in de reproduceerbaarheid van de meting en de gewenste eindnauwkeurigheid. De meetmachine moet bruikbaar zijn voor verschillende nokkenaslengte’s, en moet met absolute precisie gecenterd ingespannen kunnen worden. Wat voor invloed heeft in de praktijk een excentrische nokkenas, of een kromme of getordeerde? Moeten deze afwijkingen ook gemeten worden? De mechanische eisen voor de meetbank lijken op die van een draaibank. En zonder draai- en freesbank voor de benodigde precisie onderdelen zie ik niet hoe je de gewenste reproduceerbare eindnauwkeurigheid zou kunnen halen. Wellicht is deze vraag bij cnczone.nl meer op zijn plaats.

Berichten: 3
Geregistreerd: 13 Dec 2017, 22:50

Re: Nokkenas meetmachine (camdoctor)

Berichtdoor Dan Gouweloos » 15 Feb 2023, 21:17

Bedankt voor de reactie ,

De lineaire potmeters die ik gebruik zijn gecalibreerde potmeters speciaal voor dit doel maar een meetlineaal kan ook ik heb hier ergens op het forum daar iets over gelezen van iemand die met een arduino een draaibank uitlezing gemaakt had,
De opzet hier is dan ook om afwijkingen in de nokkenassen te registreren, te weten of de nokken ten aanzien van elkaar verdraaid zijn of afgesleten je zou zeggen dat je dat zo wel kan zien maar pint 1 de moderne motoren hebben de nokken op een pijp geperst zitten en verdraaing komt voor het is echter nagenoeg onmogelijk om dat te constateren alleen het motormanagement geeft de gekste foutcodes.
de bedoeling is om de meting van de lineaal of potmeter te triggeren en op te slaan bij iedere puls van de hoekencoder die geeft 1024 pulsen per omwenteling.

bij voorbaat dank voor het meedenken

Berichten: 3990
Geregistreerd: 16 Okt 2013, 14:31
Woonplaats: s hertogenbosch

Re: Nokkenas meetmachine (camdoctor)

Berichtdoor shooter » 16 Feb 2023, 10:33

je zou ook een micrometer kunnen gebruiken en de verdraaiing te maken met een steppermotor, dus meer een meettafel met zon kogeltje zoals heidenhain want inderdaad de resolutie is wel 1000 maar de nauwkeurigheid is maar 1%. dan heb je dus 96 stappen per mm of beter.
verder kun je de stappenmotor voor de as vertragen met een tandriem of met een tandwielen. ik heb een heel kleine stappenmotor liggen met 4000 stappen via een tandwielbox en kost ongeveer 2 piek.
en maak een schema wat je de arduino allemaal wilt programmeren daar komt dan een mooie volgorde uit en een opzet is dan zo gemaakt.
paul deelen
shooter@home.nl

Berichten: 24
Geregistreerd: 20 Jul 2022, 14:40

Re: Nokkenas meetmachine (camdoctor)

Berichtdoor Harm J Seef » 16 Feb 2023, 11:47

Ik heb de indruk dat we een klein beetje langs elkaar heen praten. Met een tandriem en de juiste poelies is de stappenmotor, en daarmee de hoekmeting het probleem niet. Verder moet een simpele, langs de nokkenas verplaatsbare meetsensor worden bedacht. Ik vermoed dat waar Dan elke nokmeting handmatig wil doen met een hoekencoder, zijn Paul en ik twee stappen verder en willen de Arduino het meetwerk laten doen. Vanuit de arduino wordt de nokkenas rondgedraaid, waarbij de meetsensor de uitslag (vectorlengte) meet. Hoek en vector worden als meetresultaat naar de PC gestuurd. Het enige wat dan nog handmatig moet gebeuren is het opschuiven van de meetsenssor van nok naar nok, zodat de arduino de volgende nokmeetcyclus kan uitvoeren. Met deze opzet kun je ook de nokkenas-balans en lager-diameters controleren, en zo ook de asvervorming. Blijft de vraag; wat is de gewenste nauwkeurigheid? 1/10 mm 1/100 mm?

Helaas, mijn forum bijlagequota is bereikt, zodat ik je een tandriem-aandrijving niet kan laten zien.

Berichten: 3
Geregistreerd: 13 Dec 2017, 22:50

Re: Nokkenas meetmachine (camdoctor)

Berichtdoor Dan Gouweloos » 19 Feb 2023, 11:36

Hallo meedenkers bedankt voor de input dusverre maar ik moet even iets verduidelijken,jammer genoeg begrijp ik niet hoe ik hier een afbeelding kan invoegen forums snap ik zowiezo niet erg goed ,anders konden jullie zien dat het mechanische deel al helemaal gebouwd is . het is een soort draaibankje geworden met aan de ene zijde een stappenmotor en een klauwplaat waar de nokkenas mee word aangedreven en aan de andere zijde ook een klauwplaat waarmee de rotatie encoder (heidenhain) wordt aangedreven door de nokkenas verder is er een hoogtemeetopstelling gemaakt die bij iedere nok gepositioneerd kan worden. de meting is hetzij als analoge spanning af te lezen hetzij digitaal met een lineaire encoder, wat ik nu wil is :per puls van de encoder(nu 1024 per omwenteling maar andere resoluties zijn ook mogelijk 512 of 360 ) de data van de hoogtemeting wegschrijven.
Dan de volgende nok meten het zou mooi zijn als ik de stappenmotor naar een gemakkelijk via het beeldscherm te programmeren of vooraf ingestelde waarden hoek kan verplaatsen en de volgende meting te starten over 360 graden.

Bijvoorbaat dank voor het meedenken m.vr gr.Dan Gouweloos

Berichten: 24
Geregistreerd: 20 Jul 2022, 14:40

Re: Nokkenas meetmachine (camdoctor)

Berichtdoor Harm J Seef » 22 Feb 2023, 11:23

Kortom de mechanische opbouw is klaar, nu de touwtjes nog. Je weet wat je wil, maar weet niet hoe. Op www.audiotech.com de cam-pro-plus gezien en heb nu een idee hoe zoiets er uit ziet. Op www.mvwautotechniek.nl/nokkenas-meten/ gezien wat de bedoeling is; meten met 1/100 mm nauwkeurigheid. Voor arduino-knutselaars wel zo handig om de exacte typenummers van de meetinstrumenten te weten. Een beeld zegt meer dan duizend woorden; probeer vooral om een foto te uploaden.

Gebruikers-avatar
Berichten: 619
Geregistreerd: 15 Nov 2015, 11:54

Re: Nokkenas meetmachine (camdoctor)

Berichtdoor Gij Kieken » 22 Feb 2023, 12:54

Een tijdje terug ben ik bezig geweest om iets te maken waarmee je de vorm van een custom dichting (bv een kleppen deksel of olie carter) kon digitaal in kaart te brengen.
De bedoeling was om de X-Y coördinaten door te geven naar Exel en vervolgens daar met AutoCad een tekening mee maken om dan uit te lazeren.
De bediening moest je manueel ingeven en iedere X-Y positie vervolgens vast leggen.
Het is niet echt wat je zoekt, maar het is misschien een inspiratie.
bijgevoegd de code.
Code: Alles selecteren
/*
  Update:   ver.06  20/11/2019
            Declare QEA and interrupt variables as volatile
            in order to reserve memory in the compiler
            Pitfall changed QEA into int8_t(negative numbers to)
            Code not tested Yet

  Purpose:  Double 4x Bi-directional encoding
            to represent the X-Y axis of a 2d object
            and log it in .csv format.
  Board:    Arduino Mega 2560
            Optical encoder open collector

  Author:   Gij Kieken

  Info:     I am using an array to determine
            the X and Y position

*/
// Used functions
/* myDebounceShortLongPress
    Purpose:  Debounce an array of push buttons and determine if they
              where pressed a short or long time.(micro seconds)
              In setup use pinMode(pin, INPUT_PULLUP) so no external
              components are necessary.
              Buttons connected 1-side to gnd the other to Arduino pin.
              Author: Gij Kieken
*/

const byte maxButton = 3;                        //Number of buttons
const byte pinPushButton[maxButton] = {4, 5, 6}; //Arduino IN pins
const byte maxOutput = 4;                        //Number of outputs
const byte LED[maxOutput] = {9, 10, 11, 12};     //Arduino OUT pins
boolean modeStatus = false;        // Keep track of Hole or Line mode
boolean printHeaderHole = true;    // Print header once
boolean printHeaderLine = false;   // Print header once
boolean printHeaderStop = false;   // Print header once
//**********************
const unsigned long interval = 500000;
unsigned long previousStartMicros;
unsigned long previousStopMicros;
boolean enabledStop = false;
boolean enabledStart = false;
//***********************
volatile long countX = 0;
volatile long countY = 0;
volatile byte stateX, statepX;
volatile byte stateY, statepY;
//Quadrature Encoder Array
volatile const int8_t QEA[16] = {0, -1, 0, 1, 1, 0, -1, 0, 0, 1, 0, -1, -1, 0, 1, 0};
volatile byte Xindex, portD_Xval;
volatile byte Yindex, portD_Yval;

void setup() {
  Serial.begin(9600);
  pinMode(21, INPUT);//Channel A
  pinMode(20, INPUT);//Channel B
  pinMode(19, INPUT);//Channel C
  pinMode(18, INPUT);//Channel D
  //Initialize push button pins as inputs with pull-ups
  // button[0]=startButton, button[1]=stopButton, button[2]=modeButton
  for (byte i = 0; i < maxButton; i++) {
    pinMode(pinPushButton[i], INPUT_PULLUP);
  }
  //Initialize LED pins as outputs
  // LED[0]=HoleLed, LED[1]= LineLed, LED[2]=StartLed, LED[3]=StopLed
  for (byte j = 0; j < maxOutput; j++) {
    pinMode(LED[j], OUTPUT);
  }
  digitalWrite(LED[0], !modeStatus);   //We start in hole mode
  digitalWrite(LED[1], modeStatus);    //LineLED=OFF
  digitalWrite(LED[2], LOW);           //StartLed=OFF
  digitalWrite(LED[3], LOW);           //StopLed=OFF
  attachInterrupt(digitalPinToInterrupt(21), Xchange, CHANGE);  //Int 0
  attachInterrupt(digitalPinToInterrupt(20), Xchange, CHANGE);  //Int 1
  attachInterrupt(digitalPinToInterrupt(19), Ychange, CHANGE);  //Int 2
  attachInterrupt(digitalPinToInterrupt(18), Ychange, CHANGE);  //Int 3

  //set initial stateX value
  portD_Xval = PIND & 0b00000011;//mask D21 and D20
  if (portD_Xval == 0b00000011) stateX = 0;
  if (portD_Xval == 0b00000010) stateX = 1;
  if (portD_Xval == 0b00000000) stateX = 2;
  if (portD_Xval == 0b00000001) stateX = 3;
 
  //set initial stateY value
  portD_Yval = PIND & 0b00000011;//mask D19 and D18
  if (portD_Yval == 0b00001100) stateY = 0;
  if (portD_Yval == 0b00001000) stateY = 1;
  if (portD_Yval == 0b00000000) stateY = 2;
  if (portD_Yval == 0b00000100) stateY = 3;
 
  // Start communication with Excel
  Serial.println("CLEARSHEET");
  Serial.println("LABEL,X-Pos,Y-Pos");
  Serial.println("CELL,SET,C01, Gij Kieken X-Y pos ");
  Serial.println("CELL,SET,C02, Long press Start to start log.");
  Serial.println("CELL,SET,C03, Short press Start to tween.");
  Serial.println("CELL,SET,C04, Short press mode to toggle.");
  Serial.println("CELL,SET,C05, Short press Stop to stop log.");
  Serial.println("DATA,HOLE-X,HOLE-Y");
}

void loop() {
  // put your main code here, to run repeatedly:
  static unsigned long previousTime = 0;
  const byte timeInterval = 2000; //pick a short time interval
  byte button[maxButton] = {}; //array to store the latest readings
  // button[0]=startButton, button[1]=stopButton, button[2]=modeButton
  // LED[0]=HoleLed, LED[1]= LineLed, LED[2]=StartLed, LED[3]=StopLed
  // - check all buttons
  if ((micros() - previousTime) > timeInterval) {
    previousTime = micros();
    for (byte i = 0; i < maxButton; i++) {
      button[i] = checkButtons(i);
    }
    if (button[0] == 1) { // Code, when Start button is short-pushed
      //***Continue to Log***
      if (enabledStart) {
        digitalWrite(LED[2], HIGH);
        Serial.print("DATA,");
        Serial.print(countX);
        Serial.print(",");
        Serial.println(countY);
        Serial.println("BEEP");
        previousStartMicros = micros();       
      }
    }
    if (button[0] == 2) { // Code, when Start button is long-pushed
      //***Start to Log***
      if (!enabledStart) {
        digitalWrite(LED[2], HIGH);
        enabledStart = true;
        // Reset countX and countY
        countX = 0;
        countY = 0;
        Serial.print("DATA,");
        Serial.print(countX);
        Serial.print(",");
        Serial.println(countY);
        Serial.println("BEEP");     
        previousStartMicros = micros();
      }
    }
    if (button[1] == 1) { // Code, when Stop button is short-pushed
      //***Stop to Log***
      digitalWrite( LED[3], HIGH);         // turn on led
      if (!printHeaderStop) {
        Serial.println("DATA,STOPPED-X,STOPPED-Y");  // Print header
        // Reset the flags
        modeStatus = LOW;                  // Reset modeStatus to hole mode
        printHeaderLine = false;
        printHeaderStop = true;            // Make sure header is printed only once
        enabledStart = false;              // Reset the start flag
        enabledStop = true;                // Print offset X=0,Y=0 once
        digitalWrite(LED[0], !modeStatus); // Change hole led state
        digitalWrite(LED[1], modeStatus);  // Change line led state
        Serial.println("DATA,HOLE-X,HOLE-Y");
        Serial.println("BEEP");
        Serial.println("SAVEWORKBOOKAS,MyNewX-Y_pos");
        printHeaderHole = true;
        previousStopMicros = micros();
      }
    }
    if (button[2] == 1) { // Code, when Mode button is short-pushed
      //***Select the mode***
      // modeStatus=0 ---> hole-modus, modeStatus=1 ---> line-modus
      modeStatus = !modeStatus;          // Toggle the LED value
      digitalWrite(LED[0], !modeStatus); // Change hole led state
      digitalWrite(LED[1], modeStatus);  // Change line led state
      //***Determine mode Hole or Line and printout appropriate header***
      if (!modeStatus && !printHeaderHole && printHeaderLine) {
        Serial.println("DATA,HOLE-X,HOLE-Y");
        Serial.println("BEEP");
        printHeaderHole = true; // Make sure header is printed only once
        printHeaderLine = false;
      }
      else if (modeStatus && printHeaderHole && !printHeaderLine) {
        Serial.println("DATA,LINE-X,LINE-Y");
        Serial.println("BEEP");
        printHeaderLine = true;
        printHeaderHole = false;
      }
    }
  }
  // Switch off start led
  if ( micros() - previousStartMicros >= interval) {
    digitalWrite( LED[2], LOW);         // turn off led
  }
  // Switch off stop led
  if ( enabledStop)  {                  // software timer is active
    if ( micros() - previousStopMicros >= interval) {
      digitalWrite( LED[3], LOW);      // turn off led
      enabledStop = false;             // stop software timer
      printHeaderStop = false;         // Reset flag
    }
  }
} // End void loop()
//************************************************************************

/*  Function: Checks one button for short or long press (micro seconds)
              Accepts a byte for the button number
              Returns a byte 0-none 1-short 2-long
   Info:      Action is executed when release button
*/
byte checkButtons(byte buttonNo) {
  const unsigned long timeDebounce = 100000;//time to debounce
  const unsigned long timeLong = 1000000;   //minimum time for Long press
  const unsigned long timeBreak = 200000;   //time interval after button release,
  //before ready for next press
  static byte state[maxButton] = {};        //this initializes all elements to zero
  static unsigned long previousTime[maxButton] = {};//this initializes all elements to zero
  byte r = 0;                              // 0:not  1:short  2:long
  if (state[buttonNo] == 0) {  //no button has been pressed - check if
    if (digitalRead(pinPushButton[buttonNo]) == LOW) {
      previousTime[buttonNo] = micros();
      state[buttonNo] = 1;
    }
  } else if (state[buttonNo] == 1) {  //button was pressed - check for how long
    if ( (micros() - previousTime[buttonNo]) > timeDebounce) {
      if ( (micros() - previousTime[buttonNo]) < timeLong) {
        if ( digitalRead(pinPushButton[buttonNo]) == HIGH) { //released -> short press
          previousTime[buttonNo] = micros();
          state[buttonNo] = 3;
          r = 1;
        }
      } else {                        //it was a long press
        state[buttonNo] = 2;
        r = 2;
      }
    }
  } else if (state[buttonNo] == 2) {  //wait for long button press to end
    if (digitalRead(pinPushButton[buttonNo]) == HIGH) {
      previousTime[buttonNo] = micros();
      state[buttonNo] = 3;
    }
  } else if (state[buttonNo] == 3) {  //wait a little while after previous button press
    if ( (micros() - previousTime[buttonNo]) > timeBreak) {
      state[buttonNo] = 0;
    }
  }
  return r;
}

//*********************************************
// Faster ISR digital Read
void Xchange() {
  cli();
  statepX = stateX;
  portD_Xval = PIND & 0b00000011;//mask D21 and D20
  if (portD_Xval == 0b00000011) stateX = 0;
  if (portD_Xval == 0b00000010) stateX = 1;
  if (portD_Xval == 0b00000000) stateX = 2;
  if (portD_Xval == 0b00000001) stateX = 3;
  Xindex = 4 * stateX + statepX;
  countX = countX + QEA[Xindex];
  sei();
}

// Faster ISR digital Read
void Ychange() {
  cli();
  statepY = stateY;
  portD_Yval = PIND & 0b00001100;//mask D19 and D18
  if (portD_Yval == 0b00001100) stateY = 0;
  if (portD_Yval == 0b00001000) stateY = 1;
  if (portD_Yval == 0b00000000) stateY = 2;
  if (portD_Yval == 0b00000100) stateY = 3;
  Yindex = 4 * stateY + statepY;
  countY = countY + QEA[Yindex];
  sei();
}

Berichten: 24
Geregistreerd: 20 Jul 2022, 14:40

Re: Nokkenas meetmachine (camdoctor)

Berichtdoor Harm J Seef » 28 Feb 2023, 11:32

Ben altijd weer verbaasd over het menselijk vernuft, en dat iedereen een oplossing bedenkt op basis van eigen opleiding en ervaringen. In feite levert Gij een concept voor een Arduino-pantograaf, om via excel en autocad bij een lasermachine uit te komen. Wanneer je met een fototoestel op forse afstand beeldvullend inzoomt zijn de randbeeldafwijkingen minimaal. Maak zo een foto van carter of kleppendeksel met een lineaal in beeld. Gebruik in QCAD (gratis, autocad-compatible) de foto als onderlegger om de gewenste pakking met rechte lijnstukjes over te trekken. Zet de lijnstukken om naar polylines. Gebruik de linaal-lengte om de tekening naar 1:1 te verschalen. Gebruik QCAD’s CAM-module (niet gratis) om de G-code aan te maken voor de lasermachine. Deze methode gebruik ik voor de inverse van een pakking, namelijk voor het aanmaken van sjablonen van logo’s, en kopie van printplaat.

Ok, leuke informatie, maar wel off topic. Wat ik mij wel afvraag is of de meetsensoren met de draaiende nokuitslag meebewegen, of dat elke meting keer op keer een handmatig omlaag en omhoog bewegen is van de meetsensor.

Terug naar Overige projecten

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers en 6 gasten