Hulp gevraagd. Project met 2 motoren die gekoppeld worden

Projecten die niet passen in bovenstaande onderwerpen
Berichten: 1
Geregistreerd: 30 Nov 2021, 22:10

Hulp gevraagd. Project met 2 motoren die gekoppeld worden

Berichtdoor sietsema » 30 Nov 2021, 22:23

Ik ben bezig met een project.
Het zijn 2 motoren die geschakeld zijn via een driver.
De enen motor wordt gestuurd en de andere moet via een PID regelaar volgen.

Om het toerental te meten heb ik een 2e arduino mega die d.m.v. 4 hall sensoren op beide motoren het toerental meet.
De motor heeft 2 sensoren omdat ik ook de draairichting wil bepalen.
De 4 hall sensoren zitten op de 4 interupt poorten van de Mega.

De 1e Arduino gebruik ik voor de controle en regeling.
Om een of andere manier gaat er iets mis wat het programma is erg traag en de regeling werkt niet.
Door direct de poorten aan te sturen probeer ik tijd te winnen maar dit geeft weinig resultaat.

Is er iemand die kan assisteren?

Dit is de code van de meet Arduino:
Code: Alles selecteren
// generike library
  #include <Wire.h>
  #include <SPI.h>

/*ingangen voor de snelheidssensoren.
  #define MotorHall1  18                                      //Ingang met interupt voor RPM bepalen
  #define MotorHall2  19                                      //Ingang met interupt voor draairichting bepalen
  #define MotorHall3  20                                      //Ingang met interupt voor RPM bepalen
  #define MotorHall4  21                                      //Ingang met interupt voor draairichting bepalen
 
//terugkoppeling naar control Arduino
  #define DraaiMotor1 31                                      //Uitgang voor indicatie van draairichting naar de andere Arduino
  #define DraaiMotor2 33                                      //Uitgang voor indicatie van draairichting naar de andere Arduino
  #define Speed1 44                                           //Uitgang voor indicatie van toerental naar de andere Arduino
  #define Speed2 46                                           //Uitgang voor indicatie van toerental naar de andere Arduino
*/

//Het instellen van de gebruikte variabelen 
  byte last_channel_1, last_channel_3;
  volatile double Hall_sensor_tijd_1, Hall_sensor_tijd_3;
  volatile unsigned long timer_1, timer_3;
  volatile int Hall_direction_tijd_1, Hall_direction_tijd_2;
  int RPM1, RPM2,TRPM1, TRPM2;

void setup() {
 
//  Serial.begin(9600);

//De pindefinitie vastzetten voor de communicatie.
  DDRD = DDRD | B00000000;                                     //Zet de pinnen in register D op ingang (18,19,20,21)
  DDRC = DDRC | B01010000;                                     //Zet de pinnen in register C op uitgang (31,33)
  DDRL = DDRL | B00101000;                                     //Zet de pinnen in register L op uitgang (44,46)
 
//  pinMode(DraaiMotor1, OUTPUT);                                //Zet pin 31 naar uitgang
//  pinMode(DraaiMotor2, OUTPUT);                                //Zet pin 33 naar uitgang
//  pinMode(Speed1, OUTPUT);                                     //Zet pin 44 naar uitgang
//  pinMode(Speed2, OUTPUT);                                     //Zet pin 46 naar uitgang
 
//interupt setup
  attachInterrupt(digitalPinToInterrupt(18),HallPuls1,RISING); //Zet de interrupt aan op ingang 18 en bij opgaande flank start subroutine
  attachInterrupt(digitalPinToInterrupt(19),HallPuls2,RISING); //Zet de interrupt aan op ingang 19 en bij opgaande flank start subroutine
  attachInterrupt(digitalPinToInterrupt(20),HallPuls3,RISING); //Zet de interrupt aan op ingang 20 en bij opgaande flank start subroutine
  attachInterrupt(digitalPinToInterrupt(21),HallPuls4,RISING); //Zet de interrupt aan op ingang 21 en bij opgaande flank start subroutine
}

void loop() {
 
 
  //Bepaal de draairichting Als de tijd tussen Hallsensor 1 en 2 kleiner is dan X draairichting links anders rechts.
  if(Hall_direction_tijd_1 < 25){
    PORTC |= B01000000;
//    digitalWrite(DraaiMotor1, HIGH);
  }   
  else{
    PORTC &= !B01000000;
//    digitalWrite(DraaiMotor1, LOW);
  }

  if(Hall_direction_tijd_2 < 25){
    PORTC |= B00010000;
//    digitalWrite(DraaiMotor2, HIGH);
  }
  else{
    PORTC &= !B00010000;
//    digitalWrite(DraaiMotor2, LOW);
  }

  //Bereken het toerental en schrijf de waarde naar een pulsbreedte voor indicatie naar andere Arduino
  RPM1 = (1/ (Hall_sensor_tijd_1 / 100000));
  TRPM1 = map (RPM1, 0, 50, 0, 255);
  OCR5C = TRPM1;
//  Serial.println(TRPM1);
//  analogWrite(Speed1, TRPM1);
 
  //Bereken het toerental en schrijf de waarde naar een pulsbreedte voor indicatie naar andere Arduino
  RPM2 = (1/ (Hall_sensor_tijd_3 / 100000));
  TRPM2 = map (RPM2, 0, 50, 0, 255);
  OCR5A = TRPM2;
//  Serial.println(TRPM2);
//  analogWrite(Speed2, TRPM2);
 
}
 
////////////      Subroutines    ////////////

void HallPuls1(void){                                           // this function will run if a pin change is detected on portB
//Tacho 1=====================================================
   if(last_channel_1 == 0){                                     // Input 8 changed from 0 to 1
    last_channel_1 = 1;                                         // Remember current state
    timer_1 = micros();                                         // Set timer_1 to micros()
    }
  else if(last_channel_1 == 1){                                 // Input 8 changed from 1 to 0
    last_channel_1 = 0;                                         // Remember current state
    Hall_sensor_tijd_1 = micros() - timer_1;                    // Calculate total micros()
    }
  }
 
void HallPuls2(void){
  if(RPM1 < 15){                                                //Zet een maximaal toerental voor bepalen draairichting
    Hall_direction_tijd_1 = micros() - timer_1;                 //Trek de tijd van sensor 1 af van de tijd van sensor 2
    }
  }

void HallPuls3(void){
//Tacho 2=====================================================
   if(last_channel_3 == 0){                                     // Input 8 changed from 0 to 1
    last_channel_3 = 1;                                         // Remember current state
    timer_3 = micros();                                         // Set timer_1 to micros()
  }
  else if(last_channel_3 == 1){                                 // Input 8 changed from 1 to 0
    last_channel_3 = 0;                                         // Remember current state
    Hall_sensor_tijd_3 = micros() - timer_3;                    // Calculate total micros()
    }
  }
 
void HallPuls4(void){
  if(RPM2 < 15){                                                //Zet een maximaal toerental voor bepalen draairichting
    Hall_direction_tijd_2 = micros() - timer_3;                 //Trek de tijd van sensor 1 af van de tijd van sensor 2
  }
}

 


Dit is de code van de regel Arduino:
Code: Alles selecteren


// library voor 2,8" TFT scherm
  #include <Adafruit_TFTLCD.h>
  #include <MCUFRIEND_kbv.h>
  MCUFRIEND_kbv tft;
  #include <TouchScreen.h>
  #include <Wire.h>
  #include <SPI.h>

//3.5 TFT scherm
  #define LCD_CS A3 // Chip Select goes to Analog 3
  #define LCD_CD A2 // Command/Data goes to Analog 2
  #define LCD_WR A1 // LCD Write goes to Analog 1
  #define LCD_RD A0 // LCD Read goes to Analog 0

//kleuren definieren
  #define BLACK   0x0000
  #define BLUE    0x001F
  #define RED     0xF800
  #define GREEN   0x07E0
  #define CYAN    0x07FF
  #define MAGENTA 0xF81F
  #define YELLOW  0xFFE0
  #define WHITE   0xFFFF

//bepalen pinnen voor motorsturing
  #define Motor1Pin1 34         //Pin zit in register PC3
  #define Motor1Pin2 35         //Pin zit in register PC2
  #define Motor2Pin1 36         //Pin zit in register PC1
  #define Motor2Pin2 37         //Pin zit in register PC0
  #define Motor1Speed 11        //Pin zit in register PB5
  #define Motor2Speed 12        //Pin zit in register PB6
 
// bepalen pinnen informatie vanuit de Speed Arduino
  #define DraaiMotor1 50        //Pin zit in register PB3
  #define DraaiMotor2 51        //Pin zit in register PB2
  #define Speed1 52             //Pin zit in register PB1
  #define Speed2 53             //Pin zit in register PB0
 
//Zet de ingangen voor de drukknoppen
  #define Button1 22            //Pin zit in register PA0

//Het instellen van de gebruikte variabelen 
  int Hall_direction_tijd_1, Hall_direction_tijd_2;
  int delay_Display = 0;
  int delay_average = 0;
  int newPosition, oldPosition, constPosition, gasPosition;
  int Draairichting_1_gemeten, Draairichting_2_gemeten, RPM1, RPM2;
  int pwm_speed1, pwm_speed2;
  byte HBridge[8];

  int Button1Status;
  int Button1Old, Button1New = 1;
  int Button1Toggle = 1;
 
  int pid_speed = 0;
  float kp = 2.25;
  float ki = 0.10;
  float kd = 0.005;
  int error = 0;
  float PIDPosition = 0;                                                 //PID berekende gaspositie
  int diff = 0;
 
  char ButtonDisplayValue1[26];
  char ButtonDisplayValue2[26];
  char *Draairichting1;
  char *Draairichting2;

  int Potmeter1 = A5;           //Pin zit in register PF5
  int PotValue = 0;
  char PotDisplayValue[24];
  char gasDisplayValue[24];
  char PIDDisplayValue[24];
  char TimeDisplayValue1[24];
  char TimeDisplayValue2[24];
  char Gemetenrichting1[26];
  char Gemetenrichting2[26];
  char TimeSpeedSensor1[24];
  char TimeSpeedSensor2[24];


void setup() {

// Zet de pinnen voor het aansturen van deH brug
  DDRC = DDRC | B00001111;                                              //Zet de pinnen in register C op uitgang of ingang

  DDRB = DDRB | B01100000;                                              //Zet de pinnen in register B op uitgang of ingang

  DDRA = DDRA | B00000000;                                              //Zet de pinnen in register A op uitgang of ingang
 
  // Initialise timers 1 for phase and frequency correct PWM
  TCCR1A = _BV(COM1A1) | _BV(COM1B1);                                   //Enable the PWM outputs OC1A and OC1B on digital pins 11 and 12
  TCCR1B = _BV(WGM13) | _BV(CS11);                                      //Set phase and frequency correct PWM and prescaler of 8 on timer 1


// initialisatie van het TFT display
  tft.begin(0x9486);
  tft.setRotation(0);
  tft.setTextSize(2);
  tft.setTextColor(WHITE, BLACK);

//  iSetAchtergrondTFT(); //Subroutine voor het schrijven van de achtergrond van het TFT scherm
  iDisplay();

}

void loop() {
 
  iUitleesPotmeter();
 
  iButUitlezen();

  iMotorControl();
 
//  iUitlezenArduino();
 
//Vertraging voor de verversing van de gegevens op het scherm, door de grote hoeveelheid data werd het programma te traag.
  if(delay_Display == 9){
    iData();
    delay_Display = 0;
  }
  else{
    if(delay_Display < 9){
      delay_Display ++;
    }
  }
}
 
////////////      Subroutines    ////////////

void iUitleesPotmeter(void){
  PotValue = analogRead(Potmeter1);                                   //Lees de potmeter waarde in.
  gasPosition = map (PotValue, 0, 1023, 0, 255);                      //Bepaal de nieuwe uitgangspositie. De ingang is 10 bits (1024) en de uitgan PWM is 8 bits (256)
}

void iButUitlezen(void){
 
  Button1New = digitalRead(Button1);                                            //digitalRead(Button1);
  if(Button1Old == 0 && Button1New == 1){
    if(Button1Toggle == 0){
      Button1Toggle = 0;
      }
      else{
        Button1Toggle = 1;
     
    }
  Button1Old = Button1New;
  }
}

void iMotorControl(void){
 
//Zet de snelheid (0 = off and 255 = max speed):
  analogWrite(Motor1Speed, gasPosition); //ENA pin
  analogWrite(Motor2Speed, RPM2); //ENB pin
//  OCR1A = gasPosition;                                                //analogWrite (11, val)
//  OCR1B = RPM2;                                                       //analogWrite (12, val)

//Zet de draairichting van de motoren
  if (Button1Toggle == 1){
    HBridge[3] =1;
    HBridge[2] =0;
  }
  else{
    HBridge[3] = 0;
    HBridge[2] = 1;
  }
 
  if (Draairichting_1_gemeten == 1){
    HBridge[1] = 1;
    HBridge[0] = 0;
  }
  else{
    HBridge[1] = 0;
    HBridge[0] = 1;
  }
  PORTC = HBridge;
}

void iUitlezenArduino(void){
//Lees de digitale ingang uit om de draairichting te ontvangen
  Draairichting_1_gemeten = digitalRead(DraaiMotor1);
  Draairichting_2_gemeten = digitalRead(DraaiMotor2);
//Meet de pulsbreedte.
  pwm_speed1 = pulseIn(Speed1, HIGH);                                 //Meet de pulsbreete in ms
  RPM1 = map (pwm_speed1, 0, 255, 0, 150);                            //Zet de breedte om in een de snelheid
  pwm_speed2 = pulseIn(Speed2, HIGH);                                 //Meet de pulsbreete in ms
  RPM2 = map (pwm_speed2, 0, 255, 0, 150);                            //Zet de breedte om in een de snelheid
}

////////////      Visualisatie    ////////////

void iDisplay(void){
/*
In deze subroutine worden alle variabelen weergegeven op het display.
De waarden worden vuinuit het gehele programma opgeslagen in de variabelen en in een keer naar het scherm geschreven.
Om de belasting niet te groot te maken op de Arduino wordt alleen tijdens het opstarten .
*/
  tft.fillScreen(BLACK);  //set de achtergrond zwart
  tft.drawRect(0, 0, 320, 480, WHITE);

  tft.setCursor(10, 10);
  tft.print( "Potmeter waarde  ="); 
 
  tft.setCursor(10, 30);
  tft.print( "Draairichting M1 =");

  tft.setCursor(10, 50);
  tft.print( "Draairichting M2 =");

  tft.setCursor(10, 70);
  tft.print("Motor M1 waarde  =");

  tft.setCursor(10, 90);
  tft.print("Motor M2 waarde  =");
 
  tft.setCursor(10, 110);
  tft.print("Toerental M1     =");
 
  tft.setCursor(10, 130);
  tft.print("Toerental M2     =");
 
  tft.setCursor(10, 150);
  tft.print("Draairichting M1 =");

  tft.setCursor(10, 170);
  tft.print("Draairichting M2 =");

}

void iData(void){
/*
In deze subroutine worden alle verschillende waarden weergegeven op het display.
De waarden worden vuinuit het gehele programma opgeslagen in de variabelen en in een keer naar het scherm geschreven.
Om de belasting niet te groot te maken op de Arduino wordt 1 keer per 20 runs uitgevoerd.
*/
  tft.setCursor(250, 10);
  snprintf(PotDisplayValue, 6, "%4i",  PotValue);
  tft.print(PotDisplayValue); 

  tft.setCursor(240, 30);
  if(Button1Toggle == 0){
    Draairichting1 = "Rechts";
  }
  else{
    Draairichting1 = "Links ";
  }
  snprintf(ButtonDisplayValue1, 7, "%s\n",  Draairichting1);
  tft.print(ButtonDisplayValue1);

  tft.setCursor(240, 50);
  if(Button1Toggle == 0){
    Draairichting2 = "Rechts";
  }
  else{
    Draairichting2 = "Links ";
  }
  snprintf(ButtonDisplayValue2, 7, "%s\n",  Draairichting2);
  tft.print(ButtonDisplayValue2);

  tft.setCursor(250, 70);
  snprintf(gasDisplayValue, 6, "%4i",  gasPosition);
  tft.print(gasDisplayValue);

  tft.setCursor(250, 90);
  snprintf(PIDDisplayValue, 6, "%4i",  PIDPosition);
  tft.print(PIDDisplayValue);
 
  tft.setCursor(250, 110);
  snprintf(TimeDisplayValue1, 6, "%4i",  RPM1);
  tft.print(TimeDisplayValue1);
 
  tft.setCursor(250, 130);
  snprintf(TimeDisplayValue2, 6, "%4i",  RPM2);
  tft.print(TimeDisplayValue2);
 
  tft.setCursor(250, 150);
  snprintf(Gemetenrichting1, 7, "%i\n",  Draairichting_1_gemeten);
  tft.print(Gemetenrichting1);

  tft.setCursor(250, 170);
  snprintf(Gemetenrichting2, 7, "%i\n",  Draairichting_2_gemeten);
  tft.print(Gemetenrichting2);
}

Advertisement

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

Re: Hulp gevraagd. Project met 2 motoren die gekoppeld worde

Berichtdoor shooter » 01 Dec 2021, 17:08

maak eerst maar eens een programma schema in de vorm van een stroomdiagram en ik zie bijvoorbeeld dat ddrc=!B01000000 dat betekent dus dat het 255-64 is dus 10111111 etc.
gaat het dan goed? met de rest
en tft schrijven duurt gewoon heel erg lang. maar dat is op de andere arduino. dat komt omdat er een hele library voor is.
paul deelen
shooter@home.nl

Berichten: 287
Geregistreerd: 15 Apr 2021, 20:05

Re: Hulp gevraagd. Project met 2 motoren die gekoppeld worde

Berichtdoor ctunes » 03 Dec 2021, 02:32

sietsema schreef: werkt niet.


WAT precies, werkt niet?

Terug naar Overige projecten

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers en 15 gasten