Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <PID_v1.h>
- #include <Wire.h> // Library für I2C-Interface
- #include <LiquidCrystal_I2C.h> // LCD i2c Library einbinden
- LiquidCrystal_I2C lcd1(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
- LiquidCrystal_I2C lcd2(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
- # define PotiPin 0
- # define HallPin 2
- # define pwmPin 9
- int Umax = 1500;
- int Prozent;
- double UpmSoll;
- double upmIst = 0;
- char buf[17];
- double pwm = 127;
- int hpin;
- const int AVG = 4; // Glättung über mindestens 4 Messwerte
- volatile unsigned long dauer = 0; // microsekunden seit dem letzten Interrupt
- volatile unsigned long last = 0; // Zählerwert beim letzten Interrupt
- volatile unsigned long average = 1; // Integrierte Dauer // =1: divide by 0 vermeiden
- volatile int avgcnt = 0;
- unsigned long previousMillis;
- int diff = 0;
- int intervall = 3200;
- double Kp = 10, Ki = 5, Kd = 1;
- PID myPID(&upmIst, &pwm, &UpmSoll, Kp, Ki, Kd, DIRECT);
- void setup() {
- Serial.begin(9600);
- //TCCR0B = (TCCR0B & 0b11111000) | 0x01;
- pinMode(PotiPin, INPUT); // lesender Zugriff
- pinMode(HallPin, INPUT_PULLUP); // dito
- pinMode(pwmPin, OUTPUT); // schreibender Zugriff
- digitalWrite(pwmPin, 0); // für definierten Anfangszustand
- attachInterrupt(digitalPinToInterrupt(HallPin), readmicros, RISING); // Interrupt
- //initialize the variables we're linked to
- hpin = analogRead(HallPin);
- UpmSoll = 0;
- upmIst = analogRead(HallPin);
- //turn the PID on
- myPID.SetMode(AUTOMATIC);
- myPID.SetTunings(Kp, Ki, Kd);
- lcd1.begin(16, 2);
- lcd1.backlight();
- lcd2.begin(16, 2);
- lcd2.backlight();
- }
- void loop() {
- // int Prozent = analogRead(0);
- //UpmSoll = map(Prozent, 0, 1023, 90, 110);
- UpmSoll = map(analogRead(PotiPin), 0, 1023, 0, 1500);
- //UpmSoll = map(Prozent, 0, 100, 0, Umax);
- /*
- UpmSoll = ((UpmSoll + 5) / 10) * 10;
- if (UpmSoll <= 20) {
- UpmSoll = 0;
- } else if (UpmSoll >= 1485) {
- UpmSoll = 1500;
- */
- myPID.Compute();
- UpmIst();
- // UpmIstAusgabe();
- if (UpmSoll < upmIst) {
- diff = upmIst - UpmSoll;
- //digitalWrite(pwmPin, HIGH);
- pwm = map(diff, 0, UpmSoll, 0, 255);
- pwm = min(pwm, 255); // Begrenzung des PWM - Wertes auf höchstens 255
- Serial.println("BREMSE AN");
- } else {
- diff = 0;
- pwm = 0;
- Serial.println("BREMSE OFF");
- }
- analogWrite(pwmPin, pwm);
- //Serial.println("EIN");
- Serial.print(" UpmSoll: ");
- Serial.print(UpmSoll);
- Serial.print(" upmIst: ");
- Serial.print(upmIst);
- Serial.print(" pwm: ");
- Serial.println(pwm);
- int intervall = 3200;
- //Lcd1();
- Lcd2();
- }
- void UpmIst (void) {
- if (dauer != 0) {
- upmIst = 60000000 / average; // Drehzahl ausrechnen und runden
- //upmIst = ((upmIst + 10) / 10) * 10;
- } else {
- upmIst = 0; // keine Messung? -> Stillstand
- avgcnt = 0;
- }
- sprintf(buf, "%4lu", upmIst);
- }
- void readmicros() { // Interrupt-Routine
- // detachInterrupt(digitalPinToInterrupt(HallPin)); // Interrupt ausschalten damit er uns nicht beißt
- int avgmax;
- unsigned long us = micros(); // Microsekundenzähler auslesen
- if (last == 0) { // erster Messwert?
- last = us; // merken und nicht weiter bearbeiten
- }
- else {
- if ( us < last ) { // Zählerüberlauf
- dauer = 4294967295 - last + us; // erzeugt einen Fehler von 1µS - vernachlässigbar 4294967295
- }
- else {
- dauer = us - last; // Differenz zum letzten Durchlauf berechnen
- }
- if (dauer > 5000) { // ignorieren wenn <= 5ms (Kontaktpreller)
- average = dauer + average * avgcnt++; // Wert in buffer und mit Faktor avgcnt glätten
- average /= avgcnt; // und zurückrechnen
- avgmax = 1000000 / dauer; // dynamische Größe des Integrationspuffers
- if (avgmax < AVG) avgmax = AVG; // Trägheit mindestens 1 Sekunde
- if (avgcnt >= avgmax) avgcnt--;
- last = us; // und wieder den letzten Wert merken
- }
- else {
- dauer = 0;
- }
- }
- //attachInterrupt(digitalPinToInterrupt(HallPin), readmicros, RISING ); // Interrupt wieder einschalten
- }
- /*
- void Lcd1(void) { // Ausgabe-Komplett am LCD1
- lcd1.clear();
- lcd1.setCursor(0, 0);
- lcd1.print("Force[Nm]:");
- lcd1.setCursor(10, 0);
- lcd1.print(Force, 3); // gewicht ausgabe
- // lcd1.setCursor(0, 1);
- //lcd1.print("Drehzahl ");
- // lcd1.print(Prozent); // UpmSoll ausgabe
- //lcd1.print("%");
- */
- void Lcd2(void) { // Ausgabe-Komplett am LCD2
- lcd2.clear(); // Soll es BLINKEN ODER NICHT????
- lcd2.setCursor(0, 0);
- lcd2.print("SOLL[U/min]:");
- lcd2.setCursor(12, 0);
- int ausgabeUpmSoll = (int)UpmSoll;
- lcd2.print(ausgabeUpmSoll); // Soll-Umdrehung ausgeben
- lcd2.setCursor(0, 1);
- lcd2.print("IST [U/min]:");
- lcd2.setCursor(12, 1);
- int ausgabeUpmIst = (int)upmIst;
- lcd2.print(ausgabeUpmIst); //Ist-Umdrehung ausgeben
- // lcd2.setCursor(12, 1);
- // lcd2.print(Umax); //Max UPM Schwellwert zum schalten der Bremse
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement