Seiten

Montag, 30. März 2015

Getting Started: Programmierung Arduino Pro Mini 5V 16Mhz

In dieser Übung wird erklärt, wie Sie ein Arduino Pro Mini 5V 16MHZ mit der Arduino-Software programmieren können. Als Programmbeispiel kann z.B. das Programm Examples/Basic/Blink verwendet.

Da das Arduino Pro Mini keinen USB-Serial Konverter integriert hat, muss die Konvertierung extern erfolgen. Dafür gibt es mehrere Möglichkeiten:


  1. Verwendung eines Arduino UNO R3
  2. Verwendung eines USB Serial Konverters von e-lioness
  3. Verwendung eines FTDI BreakoutBoards von sparkfun


Für diese Beispiele wurde am Arduino Pro Mini eine 6-polige Stiftleiste angelötet.

























Zu 1)
Verwendete Komponenten:
Arduino Pro Mini 5V 16MHz
Arduino UNO
USB Kabel
Stiftleiste
Breadboard mit Halterung
Drahtbügel
getestet auf Windows XP und OSX10.6.5 mit Arduino 22

Entfernen Sie dazu vorsichtig den ATMEGA 328 vom Arduino UNO.









































Folgende Verbindungen müssen hergestellt werden:
  • VCC vom Mini mit +5V von UNO
  • GND vom Mini mit GND von UNO
  • RX vom Mini mit RX von UNO
  • TX vom Mini mit TX von UNO
  • GRN vom Mini mit RESET von UNO

























Wählen Sie im Arduino Programm unter Tools den entsprechenden Serial Port. Unter Boards kann entweder Duemilanove or Nano w/ ATmega 328 oder Arduino Pro or Pro Mini (5V 16MHz) w/ATmega 328 ausgewählt werden. Auch wenn Sie ein UNO Board verwenden, darf es hier nicht ausgewählt werden.
Sind alle Verbindungen korrekt aufgebaut, kann das Programm upgeloadet werden. Bei diesem Schaltungsaufbau wird die "RESET - Funktion" automatisch ausgeführt.




Zu 2)
Verwendete Komponenten:
Arduino Pro Mini 5V 16MHz
USB-Serial Adapter
USB Kabel
Stiftleiste
Breadboard
Drahtbügel

getestet auf Windows XP und OSX10.6.5



















Verbinden Sie dazu:
  • VCC vom Mini mit +5V vom Konverter
  • GND vom Mini mit GND vom Konverter
  • RX vom Mini mit RX vom Konverter
  • TX vom Mini mit TX vom Konverter























Wählen Sie im Arduino Programm unter Tools den entsprechenden Serial Port. Unter Boards wählen Sie Arduino Pro or Pro Mini (5V 16MHz) w/ATmega 328 aus.
Sind alle Verbindungen korrekt aufgebaut, kann das Programm upgeloadet werden.
Bei diesem Schaltungsaufbau wird die "RESET - Funktion" nicht automatisch ausgeführt. Kurz nach dem Sie im Programm den Upload Button betätigt haben, erscheint im unteren Bereich des Programms Binary scetch size... sobald dieser Text erscheint, betätigen Sie für kurze Zeit den RESET Button am Arduino Pro mini. Kurz darauf startet der Upload.


Zu 3)
Verwendete Komponenten:
Arduino Pro mini 5V 16Mhz Kit - FTDI Konverter (beinhaltet alle Komponenten)

oder einzeln:
Arduino Pro Mini 5V 16MHz
FTDI Konverter
USB Kabel Mini/A
Stiftleiste
Breadboard
Drahtbügel
getestet auf Windows XP und OSX10.6.5

Verbinden Sie dazu:
  • VCC vom Mini mit 3V3 vom Konverter (Beim 5V Konverter liegen 5V an)
  • GND vom Mini mit GND vom Konverter
  • RX vom Mini mit TX vom Konverter
  • TX vom Mini mit RX vom Konverter
  • GRN vom Mini mit DTR(GRN) vom Konverter

    ACHTUNG: Bei diesem Konverter ist die Beschriftung von TX und RX im Vergleich mit dem vorher verwendeten Konverter vertauscht. Daher muss hier RX mit TX und TX mit RX verbunden werden.























Wählen Sie im Arduino Programm unter Tools den entsprechenden Serial Port. Unter Boards kann entweder Duemilanove or Nano w/ ATmega 328 oder Arduino Pro or Pro Mini (5V 16MHz) w/ATmega 328 ausgewählte werden.
Sind alle Verbindungen korrekt aufgebaut, kann das Programm upgeloadet werden. Bei diesem Schaltungsaufbau wird die RESET - Funktion automatisch ausgeführt.

Getting Started: Line Follower mit Arduino


Line Follower mit Arduino

Bei dieser Übung erfahren Sie, wie Sie einen einfachen "Line Follower" bauen und programmieren können.

Verwendete Bauteile:

Batterien
Schrauben, Muttern



Aufbau des Magician Chassis:














Bauen Sie das Chassis nach beiliegender Schritt-für-Schritt Anleitung auf.

Vorbereitung Motordriver:
Brechen Sie 2x8 Pin´s von der Stiftleiste ab und löten Sie diese in das Breakoutboard des Motordrivers.















Line Sensoren:
Brechen Sie 2x3 Pin´s von der Stiftleiste ab und löten Sie diese jeweils in die Line Sensoren. Die Anschlüsse der Stiftleiste sollen dabei auf die gegenüberliegende Seite des Sensors zeigen.















Nehmen Sie nun eine beiliegende Schraube M3 x 45mm und stecken Sie den Line Sensor darauf. Der Schraubenkopf muss auf der gleichen Seite sein, wie der Sensor. Dann kommt eine Mutter drauf. Ziehen Sie diese dann fest, so dass der Sensor eingeklemmt wird. Seien Sie aber vorsichtig, so dass der Sensor nicht beschädigt wird. Jetzt können Sie drei Drahtbügel auf den Sensor aufstecken (GND schwarz, VCC rot, OUT gelb). Die Schraube mit dem Sensor wird nun am Chassis befestigt. Der ideale Abstand des Sensors zum Boden beträgt 3mm.
Wiederholen Sie das für den 2. Sensor.















Montage Breadboard:
Das kleine Breadboard kann mit dem doppelseitigen Klebeband am Chassis befestigt werden. Der Motortreiber wird nun auf das Breadboard aufgesteckt.


Montage Arduino:
Der Arduino kann mit kleinen Schrauben am Chassis befestigt werden.

Verkabelung:
Verbinden Sie die Bauteile mit den Drahtbügeln nach folgendem Schaltplan:

Motor Driver:
PWM A-> Arduino Pin3
AIN2 -> Arduino Pin8
AIN1 -> Arduino Pin9
STBY -> Arduino Pin12
BIN1 -> Arduino Pin11
BIN2 -> Arduino Pin7
PWMB-> Arduino Pin5
GND -> GND

VM -> Arduino Vin
VCC -> 5V
A01-> Rechter Motor - (schwarz)
A02 -> Rechter Motor + (rot)
B02 -> Linker Motor + (rot)
B01 -> Linker Motoer - (schwarz)


Linker Line Sensor:
VCC -> 5V
OUT -> Arduino Pin4
GND -> GND

Rechter Line Sensor:
VCC -> 5V
OUT-> Arduino Pin2
GND -> GND















Das Prinzip des Line Followers:
Die beiden Sensoren  senden ein Infrarot-Licht aus, das je nach Untergrund (hell - Boden / dunkel - Linie) wird unterschiedlich viel Licht reflektiert. Dies ergibt unterschiedliche Werte für den Arduino.
Die beiden Motoren sind unterschiedlich ansteuerbar. 
Je nach Stellung des Sensors zur Linie kann sich ein Motor nach vorne drehen, still stehen oder zurück drehen. In Kombination mit dem 2. Motor gibt es 


Programmstruktur:
Es werden zuerst die Sensoren ausgelesen
Je nach Sensorwerten werden die Motoren unterschiedlich angesteuert

Zur Übersichtlichkeit werden die unterschiedlichen Zustände in Funktionen programmiert und dann individuell aufgerufen.

Diese Funktion lässt mit der Motorgeschwindigkeit s beide Motoren vorwärts drehen:
int moveforward(int s){
  digitalWrite(out_A_in_1,LOW);
  digitalWrite(out_A_in_2,HIGH);
  analogWrite(out_A_pwm,s);
  digitalWrite(out_B_in_1,LOW);
  digitalWrite(out_B_in_2,HIGH);
  analogWrite(out_B_pwm,s);
}

Diese Funktion lässt mit der Motorgeschwindigkeit s beide Motoren rückwärts drehen
int movebackward(int s){
  digitalWrite(out_A_in_1,HIGH);
  digitalWrite(out_A_in_2,LOW);
  analogWrite(out_A_pwm,s);
  digitalWrite(out_B_in_1,HIGH);
  digitalWrite(out_B_in_2,LOW);
  analogWrite(out_B_pwm,s);
}

Diese Funktion lässt mit der Motorgeschwindigkeit s den linken Motor vorwärts drehen und den rechten still stehen (leichte Kurve vorwärts, rechts)
int moveforwardright(int s){
  digitalWrite(out_A_in_1,LOW);
  digitalWrite(out_A_in_2,HIGH);
  analogWrite(out_A_pwm,s);
  digitalWrite(out_B_in_1,LOW);
  digitalWrite(out_B_in_2,HIGH);
  analogWrite(out_B_pwm,0);
}


Diese Funktion lässt mit der Motorgeschwindigkeit s den rechten Motor vorwärts drehen und den linken still stehen (leichte Kurve rückwärts, rechts)
int moveforwardleft(int s){
  digitalWrite(out_A_in_1,HIGH);
  digitalWrite(out_A_in_2,LOW);
  analogWrite(out_A_pwm,0);
  digitalWrite(out_B_in_1,HIGH);
  digitalWrite(out_B_in_2,LOW);
  analogWrite(out_B_pwm,s);
}



Diese Funktion lässt mit der Motorgeschwindigkeit s den rechten Motor vorwärts drehen und den linken rückwärts drehen (Auf der Stelle drehen, rechtsrum)
int movebackright(int s){
  digitalWrite(out_A_in_1,HIGH);
  digitalWrite(out_A_in_2,LOW);
  analogWrite(out_A_pwm,0);
  digitalWrite(out_B_in_1,HIGH);
  digitalWrite(out_B_in_2,LOW);
  analogWrite(out_B_pwm,s);
}


Diese Funktion lässt mit der Motorgeschwindigkeit s den linken Motor vorwärts drehen und den rechten rückwärts drehen (Auf der Stelle drehen, linksrum)
int movebackleft(int s){
  digitalWrite(out_A_in_1,HIGH);
  digitalWrite(out_A_in_2,LOW);
  analogWrite(out_A_pwm,s);
  digitalWrite(out_B_in_1,HIGH);
  digitalWrite(out_B_in_2,LOW);
  analogWrite(out_B_pwm,0);
}


Beispielprogramm:
Kopieren Sie dieses Beispiel in Ihre Arduino IDE und laden Sie es hoch und schon folgt Ihr Roboter der Linie.

/* Line Follower von www.physicalcomputing.at
by Benny, 2012
*/

// Pin Belegung

int QD1_Pin = 2;
int QD2_Pin = 4;
int out_A_pwm = 3;
int out_B_pwm = 5;
int out_A_in_1 = 9;
int out_A_in_2 = 8;
int out_B_in_1 = 11;
int out_B_in_2 = 7;
int out_stby = 12;


// Initialisierung der Pins und der Seriellen Schnittstelle

void setup(){

  Serial.begin(9600);
  pinMode(out_A_pwm,OUTPUT);
  pinMode(out_A_in_1,OUTPUT);
  pinMode(out_A_in_2,OUTPUT);
  pinMode(out_B_pwm,OUTPUT);
  pinMode(out_B_in_1,OUTPUT);
  pinMode(out_B_in_2,OUTPUT);
  pinMode(out_stby,OUTPUT);
  digitalWrite(out_stby,HIGH);
}

void loop(){
  // Lesen der Sensorwerte
  int QRE_Value = readqd1();
  int QRE_Value2 = readqd2();
  // Setzen der Motorstärke, je nach Volt und Schwierigkeit
  // des Terrains anpassen
  int motorst = 110;

  // Falls beide Sensoren schwarzen Untergrund liefern geradeaus
  // fahren

  if(QRE_Value > 3000 && QRE_Value2 > 3000)
  {
    moveforward(motorst);
  }

  // Falls beide Sensoren keinen schwarzen Untergrund liefern
  // anhalten und entscheiden welcher Sensor den dunkleren //Untergrund liefert, je nachdem eine Drehung mit Intervall
  // von 100 in die jeweilige Richtung.

  if(QRE_Value < 1000 && QRE_Value2 < 1000)
  {
    stopmove(); // Überarbeiten
    if(QRE_Value>QRE_Value2){
      moveforwsharpright(motorst);
      delay(100);
    }

    if(QRE_Value<QRE_Value2){
      moveforwsharpleft(motorst);
      delay(100);
    }
  }

  // Falls Sensor QD1 von dem schwarzen Untergrund stark //abweicht aber QD2 nicht, eine starke Drehung nach rechts.

  if(QRE_Value < 2500 && QRE_Value2 > 3000)
  {
    moveforwsharpright(motorst);
  }

  // Falls Sensor QD2 von dem schwarzen Untergrund stark
  // abweicht aber QD1 nicht, eine starke Drehung nach links.

  if(QRE_Value2 < 2500 && QRE_Value > 3000)
  {
    moveforwsharpleft(motorst);
  }

  // Falls Sensor QD1 schwarzen Untergrund meldet, QD2 aber
  // einen leichten Abfall des Wertes liefert, eine leichte links
  // Drehung.

  if(QRE_Value > 3000 && QRE_Value2 < 3000 && QRE_Value2 > 2500)
  {
    moveforwardleft(motorst);
  }

  // Falls Sensor QD2 schwarzen Untergrund meldet, QD1 aber
  // einen leichten Abfall des Wertes liefert, eine leichte rechts
  // Drehung.

  if(QRE_Value2 > 3000 && QRE_Value < 3000 && QRE_Value > 2500)
  {
    moveforwardright(motorst);
  }

  // Ausgabe der beiden Sensoren Werte auf dem Seriellen
  // Monitor

  Serial.print("1:");
  Serial.print(QRE_Value);
  Serial.print("2:");
  Serial.print(QRE_Value2);
}

// Die oben erklärten Funktionen

int readqd1(){
  pinMode(QD1_Pin,OUTPUT);
  digitalWrite(QD1_Pin,OUTPUT);
  delayMicroseconds(10);
  pinMode(QD1_Pin,INPUT);
  long time = micros();
  while(digitalRead(QD1_Pin) == HIGH && micros() - time < 3000);
  int diff = micros() - time;
  return diff;
}

int readqd2(){
  pinMode(QD2_Pin,OUTPUT);
  digitalWrite(QD2_Pin,OUTPUT);
  delayMicroseconds(10);
  pinMode(QD2_Pin,INPUT);
  long time = micros();
  while(digitalRead(QD2_Pin) == HIGH && micros() - time < 3000);
  int diff = micros() - time;
  return diff;
}

int moveforward(int s){
  digitalWrite(out_A_in_1,LOW);
  digitalWrite(out_A_in_2,HIGH);
  analogWrite(out_A_pwm,s);
  digitalWrite(out_B_in_1,LOW);
  digitalWrite(out_B_in_2,HIGH);
  analogWrite(out_B_pwm,s);
}
int movebackward(int s){
  digitalWrite(out_A_in_1,HIGH);
  digitalWrite(out_A_in_2,LOW);
  analogWrite(out_A_pwm,s);
  digitalWrite(out_B_in_1,HIGH);
  digitalWrite(out_B_in_2,LOW);
  analogWrite(out_B_pwm,s);
}
int moveforwardright(int s){
  digitalWrite(out_A_in_1,LOW);
  digitalWrite(out_A_in_2,HIGH);
  analogWrite(out_A_pwm,s);
  digitalWrite(out_B_in_1,LOW);
  digitalWrite(out_B_in_2,HIGH);
  analogWrite(out_B_pwm,0);
}
int moveforwardleft(int s){
  digitalWrite(out_A_in_1,HIGH);
  digitalWrite(out_A_in_2,LOW);
  analogWrite(out_A_pwm,0);
  digitalWrite(out_B_in_1,HIGH);
  digitalWrite(out_B_in_2,LOW);
  analogWrite(out_B_pwm,s);
}


int movebackright(int s){
  digitalWrite(out_A_in_1,HIGH);
  digitalWrite(out_A_in_2,LOW);
  analogWrite(out_A_pwm,0);
  digitalWrite(out_B_in_1,HIGH);
  digitalWrite(out_B_in_2,LOW);
  analogWrite(out_B_pwm,s);
}

int movebackleft(int s){
  digitalWrite(out_A_in_1,HIGH);
  digitalWrite(out_A_in_2,LOW);
  analogWrite(out_A_pwm,s);
  digitalWrite(out_B_in_1,HIGH);
  digitalWrite(out_B_in_2,LOW);
  analogWrite(out_B_pwm,0);
}

int moveforwsharpright(int s){
  digitalWrite(out_A_in_1,LOW);
  digitalWrite(out_A_in_2,HIGH);
  analogWrite(out_A_pwm,s);
  digitalWrite(out_B_in_1,HIGH);
  digitalWrite(out_B_in_2,LOW);
  analogWrite(out_B_pwm,s);
}

int moveforwsharpleft(int s){
  digitalWrite(out_A_in_1,HIGH);
  digitalWrite(out_A_in_2,LOW);
  analogWrite(out_A_pwm,s);
  digitalWrite(out_B_in_1,LOW);
  digitalWrite(out_B_in_2,HIGH);
  analogWrite(out_B_pwm,s);
}
int stopmove(){
  int moveforwardright(int s);
  digitalWrite(out_A_in_1,LOW);
  digitalWrite(out_A_in_2,HIGH);
  analogWrite(out_A_pwm,0);
  digitalWrite(out_B_in_1,LOW);
  digitalWrite(out_B_in_2,HIGH);
  analogWrite(out_B_pwm,0);
}

Viel Spass bei der Umsetzung des Projektes.
Dies ist ein Beispielcode, der jederzeit gerne verbessert werden kann.


erstellt 31.5.2012