Hallo zusammen,
ich will den DC Motor synchron zu dem Schrittmotor betreiben, dazu habe ich den Sollwert Encoder_1 auf die Welle des Schrittmotors gebaut und messe ich die Drehzahl des DC Motors mit einem zweiten Encoder_2 (Istwert) .
Code (ohne LCDMenulib2 Lib ): Funktioniert wie ich es mir vorgestellt habe
#include <AccelStepper.h>
#include <Encoder.h>
#include <PID_v1.h>
#define encoderA_1 19 // Pin A encoder(Drehgeber) 19
#define encoderA_2 18 // Pin A encoder(Drehgeber) 18
#define DIR 10 // DIR motor Driver
#define PWM_OUTPUT 11 // PWM motor Driver
#define MESSINTERVALL 1000
#define ppr 100 // Encoder 100p/r
#define r_roller 31 //Radius in mm Durchmesser 6,2cm Encoder Roller Rad
// PID Regler
double Setpoint, Input, Output; //Setpoint: Sollwert, Input: Istwert,
double Kp = 0.2, Ki = 0.3, Kd = 0.1;
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
AccelStepper stepper(1, 9, 8); //( ,9 (PUL+), 8(DIR))
volatile unsigned long isr_impulse_1 = 0; // gezählte Impulse encoder 1
volatile unsigned long isr_letzterImpuls_1 = 0; // wann der letzte Impuls encoder 1 gezählt wurde
volatile unsigned long isr_impulse_2 = 0; // gezählte Impulse encoder 2
volatile unsigned long isr_letzterImpuls_2 = 0; // wann der letzte Impuls encoder 2 gezählt wurde
static unsigned long zeit_1;
static unsigned long letzterImpuls_1; // Zeit des letzten Impulses zum Zeitpunkt der letzten Messwertausgabe
unsigned long impulse_1;
float frequenz_1;
float rps_1;
volatile float geschwindigkeit_1;
static unsigned long zeit_2;
static unsigned long letzterImpuls_2; // Zeit des letzten Impulses zum Zeitpunkt der letzten Messwertausgabe
unsigned long impulse_2;
float frequenz_2;
float rps_2;
volatile float geschwindigkeit_2;
void setup()
{
stepper.setMaxSpeed(320); // die maximal zulässige Geschwindigkeit
stepper.setAcceleration(5000); // Die gewünschte Beschleunigung in Schritten pro Sekunde
pinMode (PWM_OUTPUT, OUTPUT);
pinMode (DIR, OUTPUT);
digitalWrite(DIR, HIGH);
pinMode (encoderA_1, INPUT_PULLUP);
pinMode (encoderA_2, INPUT_PULLUP);
//turn the PID on
myPID.SetMode(AUTOMATIC);
myPID.SetOutputLimits(0, 320);
myPID.SetSampleTime(2);
attachInterrupt(digitalPinToInterrupt(encoderA_1), encodermessung_1, RISING);
attachInterrupt(digitalPinToInterrupt(encoderA_2), encodermessung_2, RISING);
}
float read_speed_encoder1(void)
{
static unsigned long ersteMessung_1;
static unsigned long letzteMessung_1;
static unsigned long Time_1;
//geschwindigkeit_1=0.0;
ersteMessung_1 = millis();
if (ersteMessung_1 - letzteMessung_1 >= MESSINTERVALL)
{
Time_1 = ersteMessung_1 - letzteMessung_1;
letzteMessung_1 = ersteMessung_1;
noInterrupts(); // Interrupts sperren
impulse_1 = isr_impulse_1;
interrupts(); // Interrupts wieder zulassen
isr_impulse_1 = 0;
zeit_1 = isr_letzterImpuls_1 - letzterImpuls_1;
letzterImpuls_1 = isr_letzterImpuls_1;
if (impulse_1 > 0)
{
rps_1 = impulse_1 / (float)(zeit_1 * ppr) * 1000L;
geschwindigkeit_1 = rps_1 * 2 * r_roller * PI;
}
else {
frequenz_1 = 0;
impulse_1 = 0;
geschwindigkeit_1 = 0;
rps_1 = 0;
}
}
return geschwindigkeit_1;
}
float read_speed_encoder2(void)
{
static unsigned long ersteMessung_2;
static unsigned long letzteMessung_2;
static unsigned long Time_2;
// geschwindigkeit_2=0.0;
ersteMessung_2 = millis();
if (ersteMessung_2 - letzteMessung_2 >= MESSINTERVALL)
{
Time_2 = ersteMessung_2 - letzteMessung_2;
letzteMessung_2 = ersteMessung_2;
noInterrupts(); // Interrupts sperren
impulse_2 = isr_impulse_2;
interrupts(); // Interrupts wieder zulassen
isr_impulse_2 = 0;
zeit_2 = isr_letzterImpuls_2 - letzterImpuls_2;
letzterImpuls_2 = isr_letzterImpuls_2;
if (impulse_2 > 0)
{
rps_2 = impulse_2 / (float)(zeit_2 * ppr) * 1000L;
geschwindigkeit_2 = rps_2 * 2 * r_roller * PI;
}
else {
frequenz_2 = 0;
impulse_2 = 0;
geschwindigkeit_2 = 0;
rps_2 = 0;
}
}
return geschwindigkeit_2;
}
void loop()
{
stepper.move(3200);
stepper.run();
Setpoint = read_speed_encoder1() * 2.59365994; //Umrechnung von der Gescwindigkeit in Pul 2.59365994
Input = read_speed_encoder2() * 2.59365994; //Umrechnung von der Gescwindigkeit in Pul
if (myPID.Compute()) {
analogWrite(PWM_OUTPUT, Output );
digitalWrite(DIR, HIGH);
}
}
void encodermessung_1()
{
isr_impulse_1++;
isr_letzterImpuls_1 = millis();
}
void encodermessung_2()
{
isr_impulse_2++;
isr_letzterImpuls_2 = millis();
}
Code (Teil)mit LCDMenulib2 Lib:
#include <AccelStepper.h>
#include <Encoder.h>
#include <PID_v1.h>
#define encoderA_1 19 // Pin A encoder(Drehgeber) 19
#define encoderA_2 18 // Pin A encoder(Drehgeber) 18
#define DIR 10 // DIR motor Driver
#define PWM_OUTPUT 11 // PWM motor Driver
#define MESSINTERVALL 1000
#define ppr 100 // Encoder 100p/r
#define r_roller 31 //Radius in mm Durchmesser 6,2cm Encoder Roller Rad
volatile unsigned long isr_impulse_1 = 0;
volatile unsigned long isr_letzterImpuls_1=0;
volatile unsigned long isr_impulse_2 = 0;
volatile unsigned long isr_letzterImpuls_2=0;
static unsigned long zeit_1;
static unsigned long letzterImpuls_1;
unsigned long impulse_1;
float frequenz_1;
float rps_1;
volatile float geschwindigkeit_1;
static unsigned long zeit_2;
static unsigned long letzterImpuls_2;
unsigned long impulse_2;
float frequenz_2;
float rps_2;
volatile float geschwindigkeit_2;
float read_speed_encoder1(void)
{
static unsigned long ersteMessung_1;
static unsigned long letzteMessung_1;
static unsigned long Time_1;
//geschwindigkeit_1=0.0;
ersteMessung_1 = millis();
if (ersteMessung_1 - letzteMessung_1 >= MESSINTERVALL)
{
Time_1 = ersteMessung_1 - letzteMessung_1;
letzteMessung_1 = ersteMessung_1;
noInterrupts(); // Interrupts sperren
impulse_1 = isr_impulse_1;
interrupts(); // Interrupts wieder zulassen
isr_impulse_1 = 0;
zeit_1 = isr_letzterImpuls_1 - letzterImpuls_1;
letzterImpuls_1 = isr_letzterImpuls_1;
if (impulse_1 > 0)
{
rps_1 = impulse_1 / (float)(zeit_1 * ppr) * 1000L;
geschwindigkeit_1 = rps_1 * 2 * r_roller * PI;
}
else {
frequenz_1 = 0;
impulse_1 = 0;
geschwindigkeit_1 = 0;
rps_1 = 0;
}
}
return geschwindigkeit_1;
}
float read_speed_encoder2(void)
{
static unsigned long ersteMessung_2;
static unsigned long letzteMessung_2;
static unsigned long Time_2;
// geschwindigkeit_2=0.0;
ersteMessung_2 = millis();
if (ersteMessung_2 - letzteMessung_2 >= MESSINTERVALL)
{
Time_2 = ersteMessung_2 - letzteMessung_2;
letzteMessung_2 = ersteMessung_2;
noInterrupts(); // Interrupts sperren
impulse_2 = isr_impulse_2;
interrupts(); // Interrupts wieder zulassen
isr_impulse_2 = 0;
zeit_2 = isr_letzterImpuls_2 - letzterImpuls_2;
letzterImpuls_2 = isr_letzterImpuls_2;
if (impulse_2 > 0)
{
rps_2 = impulse_2 / (float)(zeit_2 * ppr) * 1000L;
geschwindigkeit_2 = rps_2 * 2 * r_roller * PI;
}
else {
frequenz_2 = 0;
impulse_2 = 0;
geschwindigkeit_2 = 0;
rps_2 = 0;
}
}
return geschwindigkeit_2;
}
void encodermessung_1()
{
isr_impulse_1++;
isr_letzterImpuls_1 = millis();
}
void encodermessung_2()
{
isr_impulse_2++;
isr_letzterImpuls_2 = millis();
}
void mFunc_betrieb(uint8_t param)
// *********************************************************************
{
if(LCDML.FUNC_setup()) // ****** SETUP *********
{
// remmove compiler warnings when the param variable is not used:
LCDML_UNUSED(param);
pinMode (PWM_OUTPUT, OUTPUT);
pinMode (DIR, OUTPUT);
digitalWrite(DIR, HIGH);
stepper.setMaxSpeed(320);
stepper.setAcceleration(5000);
//turn the PID on
myPID.SetMode(AUTOMATIC);
myPID.SetOutputLimits(0,255);
myPID.SetSampleTime(2);
pinMode (encoderA_1, INPUT_PULLUP);
pinMode (encoderA_2, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(encoderA_1), encodermessung_1, RISING);
attachInterrupt(digitalPinToInterrupt(encoderA_2), encodermessung_2, RISING);
// starts a trigger event for the loop function every 100 milliseconds
LCDML.FUNC_setLoopInterval(1);
}
if(LCDML.FUNC_loop()) // ****** LOOP *********
{
stepper.move(3200);
stepper.run();
Setpoint = read_speed_encoder1()*2.59365994; //Umrechnung von der Gescwindigkeit in Pul 2.59365994
Input = read_speed_encoder2()*2.59365994; //Umrechnung von der Gescwindigkeit in Pul
if (myPID.Compute()) {
analogWrite(PWM_OUTPUT, Output );
digitalWrite(DIR,HIGH);
}
if(LCDML.BT_checkAny()) { // check if any button is pressed (enter, up, down, left, right)
// LCDML_goToMenu stops a running menu function and goes to the menu
analogWrite(PWM_OUTPUT, 0);
stepper.move(0);
stepper.run();
LCDML.FUNC_goBackToMenu();
}
}
if(LCDML.FUNC_close()) // ****** STABLE END *********
{
// you can here reset some global vars or do nothing
}
}
Mit LCDMenuLib2 funktioniert nicht, da nur Schrittmotor läuft.
Kann mir dabei jemand weiterhelfen?
Vielen Dank im Voraus
Liebe Grüße