Hallo, ich habe folgenden Code zur Messung eines Magnetfeldes an einem Rotor.
Er wir auf einen Drehteller gelegt und mittels Steppe-Motor angetrieben.
Mit der Referenzmessung soll ein Muster-Rotor eingemessen werden und die Messwerte sollen mit einer Toleranz abgespeichert werden um sie mit Prüflingen zu vergleichen.
Da der Rotor in beliebiger Position auf den Drehteller gelegt werden kann, dreht der Motor bewusst mehr als 360 Grad (18000 Steps) um sicherzustellen alle Nulldurchgänge sicher zu erfassen.
Die Referenzmessung lässt sich machen, die Toleranzzone wird gespeichert und ist im Plotter gut sichtbar.
Wenn der Rotor nun beabsichtigt etwas verdreht wird und die Messung startet, sieht man deutlich dass er aus der Toleranz fällt, weil die aufgenommenen Messkurve nicht auf den Nullpunkt gelegt wird um das Ergebnis zu vergleichen sondern zeitlich um das Stück, welches händisch verdreht wurde.
Vielleicht weiß jemand woran es liegen könnte ..
#include <AccelStepper.h>
// Pin-Konfiguration
#define STEP_PIN 16
#define DIR_PIN 17
#define ENABLE_PIN 15
#define GND_1 29
#define GND_2 31
#define REF_BUTTON_PIN 30
#define START_BUTTON_PIN 32
#define MEASURE_PIN_1 23
#define MEASURE_PIN_2 22
#define MEASURE_PIN_3 21
const int number_of_pins = 3;
const uint16_t measurement_blocks = 450;
const uint16_t steps_per_revolution = 18000;
uint16_t measurement_data[number_of_pins][measurement_blocks];
uint16_t reference_data[number_of_pins][measurement_blocks];
uint16_t upper_tolerance[number_of_pins][measurement_blocks];
uint16_t lower_tolerance[number_of_pins][measurement_blocks];
bool sensor_enabled[number_of_pins] = { true, true, true };
uint16_t virtual_zero[number_of_pins]; // dynamisch berechnet
bool is_referenced = false;
bool found_a_false = false;
AccelStepper stepper(AccelStepper::DRIVER, STEP_PIN, DIR_PIN);
void setup() {
Serial.begin(115200);
pinMode(GND_1, OUTPUT);
pinMode(GND_2, OUTPUT);
pinMode(REF_BUTTON_PIN, INPUT_PULLUP);
pinMode(START_BUTTON_PIN, INPUT_PULLUP);
pinMode(MEASURE_PIN_1, INPUT);
pinMode(MEASURE_PIN_2, INPUT);
pinMode(MEASURE_PIN_3, INPUT);
pinMode(ENABLE_PIN, OUTPUT);
digitalWrite(ENABLE_PIN, LOW);
digitalWrite(GND_1, LOW);
digitalWrite(GND_2, LOW);
stepper.setMaxSpeed(10000);
stepper.setAcceleration(6000);
Serial.println(" System gestartet. Bitte zuerst referenzieren!");
}
void loop() {
if (digitalRead(REF_BUTTON_PIN) == LOW) {
delay(50); while (digitalRead(REF_BUTTON_PIN) == LOW); delay(50);
setup_tolerances();
}
if (digitalRead(START_BUTTON_PIN) == LOW) {
delay(50); while (digitalRead(START_BUTTON_PIN) == LOW); delay(50);
if (!is_referenced) {
Serial.println(" Fehler: Bitte zuerst referenzieren!");
return;
}
Serial.println(" Starte Rotorprüfung...");
measure_rotor();
}
}
void take_measurement() {
stepper.move(steps_per_revolution);
uint16_t steps_per_block = steps_per_revolution / measurement_blocks;
uint16_t next_measure_position = stepper.currentPosition() + steps_per_block;
for (int block_index = 0; block_index < measurement_blocks; block_index++) {
while (stepper.currentPosition() < next_measure_position) {
stepper.run();
}
for (int pin_index = 0; pin_index < number_of_pins; pin_index++) {
measurement_data[pin_index][block_index] = analogRead(MEASURE_PIN_1 + pin_index);
}
next_measure_position += steps_per_block;
}
while (stepper.isRunning()) {
stepper.run();
}
}
void setup_tolerances() {
Serial.println(" Referenzierung läuft...");
take_measurement();
// virtuelle Null pro Sensor bestimmen
for (int pin_index = 0; pin_index < number_of_pins; pin_index++) {
long sum = 0;
for (int i = 0; i < measurement_blocks; i++) {
sum = sum+measurement_data[pin_index][i];
}
virtual_zero[pin_index] = sum / measurement_blocks;
sensor_enabled[pin_index] = false;
for (int i = 1; i < measurement_blocks; i++) {
if (measurement_data[pin_index][i - 1] < virtual_zero[pin_index] &&
measurement_data[pin_index][i] >= virtual_zero[pin_index]) {
sensor_enabled[pin_index] = true;
break;
}
}
if (!sensor_enabled[pin_index]) {
Serial.print(" Warnung: Kein Magnetfeld erkannt bei Sensor ");
Serial.println(pin_index + 1);
}
}
// Toleranzen und Referenzdaten speichern
for (int block_index = 0; block_index < measurement_blocks; block_index++) {
for (int pin_index = 0; pin_index < number_of_pins; pin_index++) {
uint16_t value = measurement_data[pin_index][block_index];
reference_data[pin_index][block_index] = value;
upper_tolerance[pin_index][block_index] = value * 1.10;
lower_tolerance[pin_index][block_index] = value * 0.90;
}
}
is_referenced = true;
Serial.println(" Referenzierung abgeschlossen. Anlage bereit.");
plot_reference_data();
}
void plot_reference_data() {
Serial.println(" Sende Daten für Plotter...");
Serial.println("P1_REF,P1_UP,P1_LOW,P2_REF,P2_UP,P2_LOW,P3_REF,P3_UP,P3_LOW");
for (int i = 0; i < measurement_blocks; i++) {
for (int pin_index = 0; pin_index < number_of_pins; pin_index++) {
Serial.print(reference_data[pin_index][i]);
Serial.print(",");
Serial.print(upper_tolerance[pin_index][i]);
Serial.print(",");
Serial.print(lower_tolerance[pin_index][i]);
if (pin_index < number_of_pins - 1) Serial.print(",");
}
Serial.println();
}
Serial.println(" Ende der Plotdaten.");
}
void measure_rotor() {
found_a_false = false;
take_measurement();
// Null-Durchgangs-Offset ermitteln
uint16_t zero_crossing_offset = 0;
for (int idx = 1; idx < measurement_blocks; idx++) {
if (measurement_data[0][idx - 1] < virtual_zero[0] &&
measurement_data[0][idx] >= virtual_zero[0]) {
zero_crossing_offset = idx;
break;
}
}
// Um den Null-Durchgang als Bezugspunkt zu verschieben, werden alle Messdaten um den Offset verschoben.
Serial.print(" Start-Offset: ");
Serial.println(zero_crossing_offset);
Serial.println(" Messdaten für Plotter...");
for (int block_index = 0; block_index < measurement_blocks; block_index++) {
for (int pin_index = 0; pin_index < number_of_pins; pin_index++) {
if (!sensor_enabled[pin_index]) continue;
// Verschiebe den Block-Index um den Null-Durchgangs-Offset
int shifted_index = (block_index + zero_crossing_offset) % measurement_blocks;
uint16_t current_value = measurement_data[pin_index][shifted_index];
uint16_t ref_value = reference_data[pin_index][shifted_index];
uint16_t upper_tol = upper_tolerance[pin_index][shifted_index];
uint16_t lower_tol = lower_tolerance[pin_index][shifted_index];
// Überprüfe, ob der Wert außerhalb der Toleranz ist
if (current_value < lower_tol || current_value > upper_tol) {
Serial.print("[FEHLER] ");
found_a_false = true;
}
// Ausgabe der Messwerte
Serial.print("Sensor ");
Serial.print(pin_index + 1);
Serial.print(" Block ");
Serial.print(block_index);
Serial.print(": ");
Serial.print(current_value);
Serial.print(" (Ref: ");
Serial.print(ref_value);
Serial.print(", Up: ");
Serial.print(upper_tol);
Serial.print(", Low: ");
Serial.print(lower_tol);
Serial.println();
}
}
Serial.println(" Sende Messdaten für den Plotter...");
Serial.println("P1_MEASURE,P1_UP,P1_LOW,P2_MEASURE,P2_UP,P2_LOW,P3_MEASURE,P3_UP,P3_LOW");
for (int i = 0; i < measurement_blocks; i++) {
for (int pin_index = 0; pin_index < number_of_pins; pin_index++) {
int shifted_index = (i + zero_crossing_offset) % measurement_blocks;
Serial.print(measurement_data[pin_index][shifted_index]);
Serial.print(",");
Serial.print(upper_tolerance[pin_index][shifted_index]);
Serial.print(",");
Serial.print(lower_tolerance[pin_index][shifted_index]);
if (pin_index < number_of_pins - 1) Serial.print(",");
}
Serial.println();
}
if (found_a_false) {
Serial.println(" Ergebnis: Fehlerhafter Rotor");
} else {
Serial.println("Ergebnis: Fehlerfreier Rotor");
}
}