ISR = Interrupt Service Routine
https://www.arduino.cc/en/Reference/AttachInterrupt
Eigentlich müssten es 3 Pins sein: Step Direction und Enable.
Oft wird Enable aber dauerhaft auf High gelegt.
Eine Stepper Library die die einzelnen Spulenpins direkt ansprechen nutzen da dann nichts.
Aber mann kann sich die trotzdem mal ansehen um zu sehen wie das Ganze dort programmiert wurde. Grade was Interrupts angeht.
In dem Code unten, sieht man ganz am Ende (nach dem Ende von void loop) zwei ISRs mit denen ich zwei US Sensoren auswerte.
Der Code ist noch etwas ungelenk da es mein zweites Arduino Programm überhaupt war. Trotzdem nehme ich konstruktive Kritik und Verbesserungsvorschläge gerne an, da ja jeder anders an so was geht und man ja nie auslernt. Eventuell fallen Verbessungen an, an die ich noch nicht gedacht habe.
Code:
//Zielplatform Arduino Nano
//Nutzt beide Interrupteingänge
const int us1_echo = 2;
const int us2_echo = 3;
const int us1_trig = 4;
const int us2_trig = 5;
const int lf_le = 8;
const int lf_ce = 9;
const int lf_ri = 10;
int lf_le_state = LOW;
int lf_ce_state = LOW;
int lf_ri_state = LOW;
unsigned long us1_echo_st;
unsigned long us2_echo_st;
unsigned long us1_echo_et;
unsigned long us2_echo_et;
volatile unsigned long us1_srt;
volatile unsigned long us2_srt;
unsigned long us1_dist;
unsigned long us2_dist;
unsigned long prev1micros = 0;
const long toggleinterval = 1000;
int togglestate = LOW;
volatile int us1_flag = 0;
volatile int us2_flag = 0;
char* string_[]={"Linefollow:", "US-Echo1:", "US-Echo2:", "Cycletime:"};
unsigned long prev2micros = 0;
void setup() {
Serial.begin(9600);
pinMode(us1_echo, INPUT);
pinMode(us2_echo, INPUT);
pinMode(us1_trig, OUTPUT);
pinMode(us2_trig, OUTPUT);
pinMode(lf_le, INPUT);
pinMode(lf_ce, INPUT);
pinMode(lf_ri, INPUT);
attachInterrupt(0, US1_ISR, CHANGE);
attachInterrupt(1, US2_ISR, CHANGE);
}
void loop() {
lf_le_state = digitalRead(lf_le);
lf_ce_state = digitalRead(lf_ce);
lf_ri_state = digitalRead(lf_ri);
unsigned long cur1micros = millis();
if (cur1micros - prev1micros >= toggleinterval) { //alle 10ms umschalten
prev1micros = cur1micros;
if (togglestate == LOW){
togglestate = HIGH;
digitalWrite(us1_trig, HIGH);
digitalWrite(us2_trig, LOW);
us1_echo_st = 0;
us1_flag = 0;
}else{
togglestate = LOW;
digitalWrite(us1_trig, LOW);
digitalWrite(us2_trig, HIGH);
us2_echo_st = 0;
us2_flag = 0;
}
}
us1_dist = (us1_srt / 58); // Umrechnung des Sensorwerts, ungefähr in cm (für 343m/s bei trockner Luft und 20° wäre 58,3 der genaue Wert)
us2_dist = (us2_srt / 58);
//=== Beginn Ausgabe ===
Serial.print(string_[1]);
Serial.println(us1_dist);
Serial.print(string_[2]);
Serial.println(us2_dist);
Serial.print(string_[0]);
Serial.print(lf_le_state);
Serial.print(lf_ce_state);
Serial.println(lf_ri_state);
unsigned long cur2micros = micros(); //Zykluszeit Messung
Serial.print(string_[3]);
Serial.println(cur2micros - prev2micros);
prev2micros = cur2micros;
//=== Ende Ausgabe ===
}
void US1_ISR(){
if (us1_echo_st == 0) {
us1_echo_st = micros();
} else {
us1_echo_et = micros();
++us1_flag;
}
if (us1_flag == 1) {
us1_srt = (us1_echo_et - us1_echo_st);
}
}
void US2_ISR(){
if (us2_echo_st == 0) {
us2_echo_st = micros();
} else {
us2_echo_et = micros();
++us2_flag;
}
if (us2_flag == 1) {
us2_srt = (us2_echo_et - us2_echo_st);
}
}
PS: Das DRV8825 breakout Board ist glaube ich pinkompatibel zu dem vom A4988. Da sollte der selbe Code gehen.
http://forum.arduino.cc/index.php?topic=133894.0
Lesezeichen