Guten Abend. Ich habe mir eine Platine gebaut mit der ich zwei Schrittmotoren über einen Schrittmotortreiber ansteuere. Die Steuerung der Treiber übernimmt ein ATMEGA 328P.
Zur Steuerung benutze ich den Accelstepper. Die Steuerdaten werden über CAN Bus empfangen. Meistens läuft alles wunderbar. Manchmal läuft nur ein Schrittmotor und der andere nicht. Auch funktioniert die Abschaltung der Treiber mit distanceToGo() nicht immer. Vielleicht hat jemand eine Idee wo die Probleme liegen könnten. Die Steuerdaten über den Bus kommen immer richtig an das habe ich mit dem Seriellen Monitor überprüft.
#include <AccelStepper.h>
#include <AccelStepperWithDistance.h>
#include <SPI.h>
#include <mcp2515.h>
#include "stepper.h"
//CAN Bus
MCP2515 mcp2515(10); //Slave Select Pin configuration
struct can_frame canMsg; //Datatype for canMsg
//Merker CAN Daten
int DRV1speed;
int DRV1dir;
int DRV1step1;
int DRV1step2;
long DRV1steps;
int DRV2speed;
int DRV2dir;
int DRV2step1;
int DRV2step2;
long DRV2steps;
byte canID;
//Programmvariablen
const int ModuleID = 0x120; //ModulID Reihe "1" /Spalte "1" /EmpfangsID "0"
const int SpeedMax = 30;
const bool DRV1 = 0;
const bool DRV2 = 1;
bool stepper_start = false;
//AccelStepper Objekte für das Programm erstellen
AccelStepper DRV1stepper = AccelStepper(AccelStepper::DRIVER, DRV1_stepPin, DRV1_dirPin);
AccelStepper DRV2stepper = AccelStepper(AccelStepper::DRIVER, DRV2_stepPin, DRV2_dirPin);
void setup() {
Serial.begin(9600);
//Konfiguration MCP2515
mcp2515.reset(); //Can Controller zurücksetzen
mcp2515.setBitrate(CAN_125KBPS); //Übertragungsrate einstellen
mcp2515.setNormalMode(); //Kommunikations Modus
//Pin und Port configuration
pinMode(DRV1_dirPin, OUTPUT);
pinMode(DRV1_stepPin, OUTPUT);
pinMode(DRV2_dirPin, OUTPUT);
pinMode(DRV2_stepPin, OUTPUT);
pinMode(DRV1_faultPin, INPUT);
pinMode(DRV2_faultPin, INPUT);
DDRB |= 0b00000010;
//Microstepping einstellen
Microstep(DRV1, 4); // 1/4 Microsteps
Microstep(DRV2, 4); // 1/4 Microsteps
//Stepper-Driver einstellungen
DRV1stepper.setMaxSpeed(3000); //Driver1 Maximale Geschwindigkeit einstellen
DRV1stepper.setAcceleration(1000.0); //Driver1 Beschleunigung einstellen Schritte/s
DRV2stepper.setMaxSpeed(3000); //Driver2 Maximale Geschwindigkeit einstellen
DRV2stepper.setAcceleration(1000.0); //Driver2 Beschleunigung einstellen Schritte/s
Disable; //Driver ausschalten
}
void loop() {
//Steuerdaten auswerten und Stepper starten
//sobald eine Nachricht mit der ModuelID empfangen wurde
if (mcp2515.readMessage(&canMsg) == MCP2515::ERROR_OK && ModuleID == canMsg.can_id)
{
//Daten der Datenbytes in CAN Merkern speichern
DRV1step1 = canMsg.data[0];
DRV1step2 = canMsg.data[1];
DRV1dir = canMsg.data[2];
DRV1speed = canMsg.data[3];
DRV2step1 = canMsg.data[4];
DRV2step2 = canMsg.data[5];
DRV2dir = canMsg.data[6];
DRV2speed = canMsg.data[7];
//Teilstrecken in Gesamtstrecke umrechten
DRV1steps = (DRV1step1 << 8) + DRV1step2;
DRV2steps = (DRV2step1 << 8) + DRV2step2;
//Strecke in Steps umwandeln
DRV1steps = DRV1steps*9.1; // Rechnung: 1 / 0.11 mm/Schritt = 9.1 Schritte/mm
DRV2steps = DRV2steps*9.1;
//Umwandlung in negative Strecke
if (DRV1dir == 1) {
DRV1steps *= -1;
}
if (DRV2dir == 1) {
DRV2steps *= -1;
}
//Errechnen der Geschwindigkeit
DRV1speed = (DRV1speed * SpeedMax);
DRV2speed = (DRV2speed * SpeedMax);
//Geschwindigkeitsbegrenzung auf MaxSpeed 3000 Steps/s
if(DRV1speed > 3000) DRV1speed = 3000;
if(DRV2speed > 3000) DRV2speed = 3000;
//Steuerdaten zuweisen und Stepper-Driver einschalten
DRV1stepper.move(DRV1steps);
DRV1stepper.setMaxSpeed(DRV1speed);
DRV2stepper.move(DRV2steps);
DRV2stepper.setMaxSpeed(DRV1speed);
stepper_start = true;
Enable;
}
//Schrittmotoren starten
//1 Schritt pro Aufruf
DRV1stepper.run();
DRV2stepper.run();
//Stepper ausschalten wenn Strecke gefahren wurde
if (DRV1stepper.distanceToGo() == 0 and DRV2stepper.distanceToGo() == 0 and stepper_start == true) {
Disable; //Driver ausschalten
stepper_start = false; //Merker ob der Motor läuft auf false setzen
canMsg.can_id = 0x121; //ID der CAN Nachricht
canMsg.can_dlc = 1; //Anzahl Datenbytes
canMsg.data[0] = 1; //Datenbyte
mcp2515.sendMessage(&canMsg); //Senden der CAN Nachricht "Strecke gefahren Motor steht" an die SPS
}
}