Ich habe ein Arduino-Projekt was jetzt nicht direkt mit dem RFx000 zu tun hat, aber für eventuelle erweiterungen durchaus interessant werden kann.
Ich möchte meiner BF30 Fräse einen Z-Antrieb verpassen. Dazu habe ich nun folgendes gemacht. Leadshine Endstufe DM556 und 5A Stepper geordert.
Dazu einen original UNO R3 und ein LCD-Display 4x20.
Die Aufgabe ist eigentlich ersteinmal trivial. Es soll ein Poti/Joystick eine Geschwindigkeit vorgeben und der DM556 die Pulse senden. Diese Pilse erzeugen einen Steppuls der an den Stepper signalisiert wird. Steps/Umdrehung, Untersetzung und Weg pro Step werden als Konstanten definiert. Das Display wird per I2C angesteuert und benötigt so eigentlich nur SCL und SDA am Arduino UNO. Die verwendete Lib blockiert aber leider auch A4 und A5 des UNO weil manche Clone SDA und SCL nicht als Pins auf dem Board haben. Das muss man der LIB noch abgewöhnen. Wie? Keine Ahnung
Hier ist der Code den ich habe, der aber ohne Interrupts läuft. Das bedeutet wenn der UNO nur die Steppulse ausgeben soll ist es einigermassen flüssig. Muss aber auch das Display angesteuert werden geht es in den Keller mit dem Speed - klar. Alles kann der Kleine nicht im Loop machen.
Also muss ein Timer her um die Steppulse über einen Interrupt zu steuern. Das Poti/Joystick soll den Timer setzen. Also auch hier ein Interrupt. Es soll per Mittenstellung eines 10KOhm Potis nichts passieren. Nach 0 Ohm soll ganz schnell rauf und nach 10KOhm schnell nach unten gefahren werden. Zur mitte in Analog eben lsangsamer werdend.
Ein Schalter für den Eilgang setzt dann noch die Multiplikatoren für den Speed (Schleichgang, Eilgang).
Hier der Code den ich habe, der auch funktioniert aber eben ohne Interrupts.
Code: Alles auswählen
// Parameter und Definitionen nach Gusto anpassen
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
// Ausgangs-Pins
#define READY 13 // Bereitschaft
#define STEP 12 // Pin fuer Step-Impuls
#define DIRP 11 // Pin fuer Richtung
//#define ENABLE 3 // Pin fuer Enable fuer die Stepper-Endstufe
#define BACKLIGHT_PIN 3
#define En_pin 2
#define Rw_pin 1
#define Rs_pin 0
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7
// Eingangs-Pins
#define POTI A1 // Analogeingang fuer Poti
#define SWITCH A0 // Geschwindigkeits-Wahlschalter
// Poti-Paramter
#define Puse 90 // nutzbarer Drehwinkel des Potis in % (max. 100)
#define Ruhe 20 // Ruhezone in % (min. 1)
#define MITTE 512 // ADC-Wert Poti in Mittelstellung
// sollte nicht allzu weit von 512 abweichen
// Schrittfrequenz
#define Fmin 4 // Minimale Schrittfrequenz - nicht kleiner als 1
#define Fmax 4000 // Maximale Schrittfrequenz - nicht groesser als 4200
#define RFAKTOR 8 // Reduktionsfaktor Slow-Mode
#define RICHTUNG 1 // Richtungsumkehr: auf 0 oder 1 setzen je nach Wunsch
#define RELEASE 1 // Schrittmotor "loslassen" in Ruhestellung? 0/1
// ab hier nichts mehr ändern
#define I2C_ADR_Display 0x27 // Adresse Display
#define Pmin ((335544L * Ruhe) >> 16) // Minwert vom Poti
#define Pmax ((335544L * Puse) >> 16) // Maxwert vom Poti
char cBuffer[5]; // Variablen für LCD Ausgabe
int p, s, l;
int f = Fmax;
long d;
int aRead() {
int v = analogRead(POTI) - MITTE; // 0-1023 -> -512 .. +511
v <<= 2; // ganz einfache Glaettung
v += l;
v += l;
v += l;
v >>= 2;
l = v;
v >>= 2;
return v;
}
//Displayinstanz lcd erstellen
LiquidCrystal_I2C lcd(I2C_ADR_Display,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin, BACKLIGHT_PIN, POSITIVE);
void setup() {
uint8_t i, r;
pinMode(READY, OUTPUT); // Bereitschaftsanzeige
pinMode(STEP, OUTPUT); // Step
pinMode(DIRP, OUTPUT); // Richtungs-Pin
//disabled by RIU pinMode(ENABLE, OUTPUT); // Enable-Pin
pinMode(SWITCH, INPUT); // Geschwindigkeits-Wahlschalter
digitalWrite(SWITCH, HIGH); // Pullup
//disabled by RIU digitalWrite(ENABLE, LOW); // Enable 0
Wire.begin();
lcd.setBacklightPin(3,POSITIVE); //LCD init und ausgabe starten
lcd.setBacklight(1);
lcd.begin(20,4); // oder lcd.begin(16,2); für meine 16/2 Displays
lcd.clear();
lcdWrite(0,0,"Initialisiere...");
while (--i) { // Warten bis sich der ADC stabilisiert
aRead();
delay(3);
digitalWrite(READY, (i & 0x40) ? HIGH : LOW);
}
lcd.setCursor(0,1);
lcd.print("ACD stabil...");
if (abs(l) > (Pmin * 4/5)) r++;
while (r) { // Warten bis Poti stabil in Ruhezone
aRead();
if (abs(l) < (Pmin * 4/5)) r++;
delay(1);
digitalWrite(READY, (i++ & 0x20) ? HIGH : LOW);
}
lcdWrite(2,0,"Poti Mittenstellung!");
digitalWrite(READY, HIGH); // Bereit
lcdWrite(3,0,"Bereit!");
delay(3000);
lcdSetup();
}
void loop() {
p = aRead(); // geglaetteten Potiwert holen
lcdWrite(3,0,itoa(p,cBuffer,10)); // Potiwert für Debugging in Zeile 4
getSpeed();
digitalWrite(STEP, LOW); // Impuls-Pin auf low
#if RICHTUNG > 0
digitalWrite(DIRP, (p < 0) ? HIGH : LOW); // Richtungs-Pin fuer Stepper
#else
digitalWrite(DIRP, (p > 0) ? HIGH : LOW); // Richtungs-Pin fuer Stepper
#endif
p = abs(p); // 0 .. 512 -> Geschwindigkeit
if (p > Pmin) { // aus Ruhezone?
//disabled by RIU digitalWrite(ENABLE, HIGH); // Enable 1
p = constrain(p, Pmin, Pmax); // Werte begrenzen
if (digitalRead(SWITCH)) {
lcdWrite(0,8,"Eilgang ");
f = map(p, Pmin, Pmax, Fmin, Fmax); // und Poti -> Frequenz mappen
} else {
lcdWrite(0,8,"Schleichgang");
f = map(p, Pmin, Pmax, Fmin, Fmax / RFAKTOR);
}
if (f > 63) { // delayMicroseconds kann max. 16383us
d = 1000000L / f;
d -= 234; // Laufzeitkorrektur um 234us
if (d > 0) delayMicroseconds(d);
} else { // bei > 16ms keine Laufzeitkorrektur noetig
delay(1000 / f);
}
digitalWrite(STEP, HIGH); // Step an Impuls-Pin
#if RELEASE > 0
} else {
//disabled by RIU digitalWrite(ENABLE, LOW); // Enable 0 - "loslassen"
#endif
}
}
////////////////////////////////////////////////////////
void lcdSetup() {
lcd.clear(); // Erstmal alles löschen
lcdWrite(0,0,"Geschw.:");
lcdWrite(2,0,"Z Pos :");
lcdWrite(2,12,"0,000 mm");
getSpeed();
}
void getSpeed(){
if (digitalRead(SWITCH)) {
lcdWrite(0,8,"Eilgang ");
} else {
lcdWrite(0,8,"Schleichgang");
}
}
void lcdWrite (int iRow,int iCol,String sValue){
lcd.setCursor(iCol,iRow);
lcd.print(sValue);
}
Frage. Kann ich analogen Eingängen eigentlich einen Interrupt geben?
Das Fritzing mache ich gerade.
Der Hauptcode ist von hier. Die Implementation des LCD ist von mir.
Lieben Gruß,
Udo