Quellcode, Arduino-"sketches"

Arduino-"sketches":

1) Hardwaretest

Um die Hardware auf funktionalität zu testen reicht ein (für beide Motortreiber gültiger) einfacher Code:

#define EN_PIN 2 //enable (CFG)
#define DIR_PIN 4 //direction
#define STEP_PIN 3 //step

//float timevar = 5000; //Pololu A4988
float timevar = 312.5; //SilentStepStick

void setup()
{
pinMode(EN_PIN, OUTPUT);
digitalWrite(EN_PIN, HIGH); //deactivate driver (LOW active)
pinMode(DIR_PIN, OUTPUT);
digitalWrite(DIR_PIN, LOW); //LOW or HIGH
pinMode(STEP_PIN, OUTPUT);
digitalWrite(STEP_PIN, LOW);

digitalWrite(EN_PIN, LOW); //activate driver
}
void loop()
{
digitalWrite(STEP_PIN, HIGH);
delayMicroseconds(timevar/2);
digitalWrite(STEP_PIN, LOW);
delayMicroseconds(timevar/2);
}
Dabei ist zu beachten, dass das Programm nur für den Steckplatz 1 auf dem "FabScanShield" gültig ist. Für die anderen Steckplätze müssen die "defines" angepasst werden.

Außerdem beträgt die Variable "timevar" im Falle des "A4988" 5000 und im Falle des "SilentStepStick" 312,5. Die entsprechende Zeile muss auskommentiert werden.

Die unterschiedlichen Werte und die daraus resultierenden unterschiedlichen Frequenzen auf dem "STEP_PIN" hängen damit zusammen, dass der "A4988" Vollschritte und der "SilentStepStick" 16tel Schritte läuft.

Der Ablauf des Programms ist begründet durch das sogenannte "step/dir-interface" der beiden Motortreiber. Bei jeder positiven Flanke auf dem "STEP_PIN" dreht der Schrittmotor einen (Voll-, oder Teil-)Schritt weiter. Über den "DIR_PIN" lässt sich die Richtung vorgeben.









2) dB-Messung

Für die Messung des Betriebsgeräusches wurde eine Anwendung geschrieben, auf welcher sich die Drehzahl per "COM-Link" programmieren lässt:

#define EN_PIN 2 //enable
#define DIR_PIN 4 //direction
#define STEP_PIN 3 //step
#include "CurieTimerOne.h"

float temp=0;
String tempstring;

void setup()
{
pinMode(EN_PIN, OUTPUT);
digitalWrite(EN_PIN, HIGH); //deactivate driver (LOW active)
pinMode(DIR_PIN, OUTPUT);
digitalWrite(DIR_PIN, LOW); //LOW or HIGH
pinMode(STEP_PIN, OUTPUT);
digitalWrite(STEP_PIN, LOW);
digitalWrite(EN_PIN, LOW); //activate driver
Serial.begin(9600);

}

void loop()
{
tempstring = Serial.readString();
if(tempstring=="stop"){CurieTimerOne.pwmStop();}
temp = tempstring.toFloat();
if(temp){TMC2100(temp);} //silentstepstick
//if(temp){A4988(temp);} //pololu
temp=0;
}

void A4988( float n )
{
Serial.print("neue Drehzahl A4988: ");
Serial.print(n);
Serial.print(" U/s");
Serial.print('\n');
n = 5000/n;
CurieTimerOne.pwmStart(3, 25.0, n);
}

void TMC2100( float n )
{
Serial.print("neue Drehzahl TMC2100: ");
Serial.print(n);
Serial.print(" U/s");
Serial.print('\n');
n = 312.5/n;
CurieTimerOne.pwmStart(3, 25.0, n);
}
Nach wie vor muss, abhängig vom Motortreiber, eine Zeile auskommentiert werden.

Mit dem Befehl "Serial.begin(9600);" wird eine serielle Schnittstelle mit der Baudrate 9600 initialisiert. Der Befehl "Serial.readString();" lässt den "Arduino" aktiv "zuhören". Wird dann seriell etwas empfangen, gibt die Funktion das im "return" zurrück. Mit diesen Befehlen lässt sich bereits eine ( zumindest unidirektionale, Richtung PC mittels "Serial.print();" ) serielle Kommunikation realisieren.

Die Funktionen A4988() und TMC2100() werden benötigt, da die per seriell übergebene ( gewünschte ) Drehzahl in die benötigte Frequenz umgerechnet werden muss. Da der "A4988" im Vollschrittmodus und der "TMC2100" ( TMC2100 ist der Chip auf dem "SilentStepStick", hier als Synonym verwendet ) im 16tel Schrittmodus läuft braucht es unterschiedliche Umrechnungsvorschriften.

Schließlich startet die jeweilige Funktion eine "PWM" mit der errechneten Frequenz. Die "CurieTimerOne.pwm"-Funktion wurde hier benutzt um eine Frequenz zu generieren. Das Tastverhältnis spielt in diesem Fall keine Rolle.


































3) Fernsteuerung per BLE ( "bluetooth low energy" )

#include <CurieBLE.h>
#define EN_PIN 2 //enable
#define DIR_PIN 4 //direction
#define STEP_PIN 3 //step
#include "CurieTimerOne.h"

BLEPeripheral blePeripheral;
BLEService ledService("19B10000-E8F2-537E-4F6C-D104768A1214");
BLEUnsignedIntCharacteristic switchCharacteristic("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);
BLEFloatCharacteristic floatZahl("19B10002-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);


const int ledPin = 13;
float temp=0;
bool select = 0;
String tempstring;

void setup()
{
//-------BLE
blePeripheral.setLocalName("LED");
blePeripheral.setAdvertisedServiceUuid(ledService.uuid());
blePeripheral.addAttribute(ledService);
blePeripheral.addAttribute(switchCharacteristic);
blePeripheral.addAttribute(floatZahl);
switchCharacteristic.setValue(0);
floatZahl.setValue(0);
blePeripheral.begin();
//-------Motortreiber Pins
pinMode(EN_PIN, OUTPUT);
digitalWrite(EN_PIN, HIGH); //deactivate driver (LOW active)
pinMode(DIR_PIN, OUTPUT);
digitalWrite(DIR_PIN, LOW); //LOW or HIGH
pinMode(STEP_PIN, OUTPUT);
digitalWrite(STEP_PIN, LOW);
digitalWrite(EN_PIN, LOW); //activate driver
//-------SERIELL
Serial.begin(9600);
Serial.print("BLE Peripheral");
}

void loop()
{
BLECentral central = blePeripheral.central();
if (central)
{
Serial.print("Connected to central: ");
Serial.println(central.address());

while (central.connected())
{
//if (switchCharacteristic.written()){;}
if (floatZahl.written())
{
if(floatZahl.value()==999){Serial.print("SilentStepStick");Serial.println();select=0;}
if(floatZahl.value()==998){Serial.print("A4988");Serial.println();select=1;}
if(floatZahl.value()<=3&&select==0){TMC2100(floatZahl.value());}
if(floatZahl.value()<=3&&select==1){A4988(floatZahl.value());}
if(floatZahl.value()==0){CurieTimerOne.pwmStop();}
}
}
}
}

void A4988( float n )
{
Serial.print("neue Drehzahl A4988: ");
Serial.print(n);
Serial.print(" U/s");
Serial.print('\n');
n = 5000/n;
CurieTimerOne.pwmStart(3, 25.0, n);
}

void TMC2100( float n )
{
Serial.print("neue Drehzahl TMC2100: ");
Serial.print(n);
Serial.print(" U/s");
Serial.print('\n');
n = 312.5/n;
CurieTimerOne.pwmStart(3, 25.0, n);
}
Dieser Code für den "Arduino" empfängt über "BLE" Daten und wertet sie aus.

Die Smartphone-Applikation übergibt dabei eine "float"-Zahl und der "Arduino" stellt entweder die Drehzahl ein, oder invertiert die "select"-Variable. Die "select"-Variable hält fest, welcher Motortreiber ausgewählt wurde.