Hallo,
ich möchte bei einem Proxxon Bohrschleifer IBS/E per PWM die Drehzahl mit eine Arduino regeln.
Der Bohrschleifer soll allerdings auch ohne angeschlossenes PWM-Signal funktionieren. Dazu habe ich folgendes gefunden:
Ich bin umgezogen.
Die Drehzahl soll mit einem Hallsensor erfasst werden und somit die Ist-Geschwindigkeit zur Soll-GeschwindigkeitGeregelt werden.
Hier ein paar Zeichnungen der Schaltung:
Bohrschleifer und PWM Eingangsschaltung:
Fritzing Sketch:
Dazu habe ich versucht folgende Codes zu vereinen:
PWM-Code:
int sensorPin = 0;
int pwmPin = 9;
int sensorValue = 0;
void setup() {
pinMode(pwmPin, OUTPUT);
// initialize serial communication at 9600 bits per second:
TCCR1B = TCCR1B & 0b11111000 | 0x01;
Serial.begin(9600);
}
// the loop routine runs over and over again forever:
void loop() {
// read the input on analog pin 0:
sensorValue = analogRead(sensorPin);
// print out the value you read:
Serial.println(sensorValue);
analogWrite(pwmPin,sensorValue / 4);
delay(1); // delay in between reads for stability
}
Drehzahlerfassung:
volatile short rpmcount;
volatile int status;
unsigned int rpm;
unsigned long timeold;
void rpm_fun(){
rpmcount++;
if (status == LOW) {
status = HIGH;
}else{
status = LOW;
}
//digitalWrite(statusPin, status);
}
void setup(){
Serial.begin(9600);
//Interrupt 0 is digital pin 2, so that is where the IR detector is connected
//Triggers on FALLING (change from HIGH to LOW)
attachInterrupt(0, rpm_fun, RISING);
rpmcount = 0;
rpm = 0;
timeold = 0;
status = LOW;
}
void loop() {
//Update RPM every second
delay(1000);
detachInterrupt(0);
rpm = 30*1000/(millis() - timeold)*rpmcount;
timeold = millis();
rpmcount = 0;
Serial.print(rpm,DEC);
Serial.print(" =U/min\n");
attachInterrupt(0, rpm_fun, RISING);
}
PID-Regelung: Arduino Playground - PIDLibrary
/********************************************************
* PID Basic Example
* Reading analog input 0 to control analog PWM output 3
********************************************************/
#include <PID_v1.h>
//Define Variables we'll be connecting to
double Setpoint, Input, Output;
//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint,2,5,1, DIRECT);
void setup()
{
//initialize the variables we're linked to
Input = analogRead(0);
Setpoint = 100;
//turn the PID on
myPID.SetMode(AUTOMATIC);
}
void loop()
{
Input = analogRead(0);
myPID.Compute();
analogWrite(3,Output);
}
Mein Versuch dieses zu vereinen:
#include <PID_v1.h>
// pins
const int PWMpin = 9; // PWM Output Pin
const int RPMint = 0; // RPM Input Interupt (INT 0 pin 2)
//RPM Variablen
volatile short rpmcount;
volatile int state;
double rpm;
//PID Variablen
double setrpm, output, Kp = 1, Ki = 1, Kd = 0;
unsigned long timeold;
//Specify the links and initial tuning parameters
PID myPID(&rpm, &output, &setrpm, Kp,Ki,Kd, DIRECT);
void rpm_fun(){
rpmcount++;
if (state == LOW) {
state = HIGH;
}else{
state = LOW;
}
//digitalWrite(statusPin, state);
}
void setup(){
Serial.begin(9600); //Serial Conection
//Set Pin Modes
pinMode(PWMpin, OUTPUT);
// set PWM frequncy for bin 9 to 31.250 kHz
TCCR1B = (TCCR1B & 0b11111000) | 0x02;
//Triggers on FALLING (change from HIGH to LOW)
attachInterrupt(RPMint, rpm_fun, FALLING);
rpmcount = 0;
rpm = 0;
timeold = 0;
state = LOW;
setrpm = 0;
//turn the PID on
myPID.SetMode(AUTOMATIC);
}
void loop() {
// Get Set RPM per Serial Conection
if (Serial.available() > 0) {
setrpm = Serial.read();
} else {
setrpm = 0;
}
delay(1000);
detachInterrupt(RPMint);
rpm = 30*1000/(millis() - timeold)*rpmcount;
timeold = millis();
rpmcount = 0;
Serial.print("Soll: ");
Serial.print(setrpm);
Serial.print(" U/min | ");
Serial.print("Ist: ");
Serial.print(rpm);
Serial.print(" U/min \n");
myPID.Compute();
analogWrite(PWMpin,255-output);
attachInterrupt(RPMint, rpm_fun, FALLING);
}
Nur ist der Versuch mit wenig Erfolg gekrönt, da nun periodisch PWM Signale von 0 bzw. 255 erzeugt werd, die den Proxxon immer nur kurz voll beschleunigen und dann wieder austruddeln lassen.
Vielleicht kann mir hier im Forum jemand auf die Sprünge helfen.
Gruß
borsti87