kramann.info
© Guido Kramann

Login: Passwort:










kramann.info
© Guido Kramann

Login: Passwort:




Einführung in die Mikrocontrollertechnik

(EN google-translate)

(PL google-translate)

  • 1 -- 20|03|2018 -- TUESDAY

Beschreibung der Architektur eine Mikrocontrollers

40_Mikrocontroller/01_Einfuehrung/01_Entwicklungsgeschichtliches/
40_Mikrocontroller/01_Einfuehrung/02_Maschinensprache/

Maschinensprache und Assembler im Unterschied zu C

40_Mikrocontroller/01_Einfuehrung/03_Assemblerbeispiel/
40_Mikrocontroller/01_Einfuehrung/04_Sprachwahl/

Der Arduino Micro -- Pinlayout

96_Arduino/

Getting started -- Lauflicht

96_Arduino/01_Lauflicht/
  • 2 -- 27|03|2018 -- TUESDAY

Erste Übung

45_Mikro17/02_ArduinoMicro/04_Uebung/

Musterlösungen

lauflicht.zip lauflicht.zip
lauflicht_b.zip lauflicht_b.zip
uebung24.zip uebung24.zip

Digitale Ein- und Ausgänge

40_Mikrocontroller/01_Einfuehrung/05_Praxis/01_Digital_IO/
40_Mikrocontroller/01_Einfuehrung/05_Praxis/02_Byteoperationen/
40_Mikrocontroller/03_DigitalIO/01_Elektrische_Eigenschaften/
40_Mikrocontroller/03_DigitalIO/02_Pullup_Widerstaende/
40_Mikrocontroller/03_DigitalIO/03_Bitmasken_Eingang/
40_Mikrocontroller/03_DigitalIO/04_Bitmasken_Ausgang/
96_Arduino/22_Universal/02_LED_Leiste/
  • 3 -- 10|04|2018 -- TUESDAY

Erzeugung von PWM-Signalen und die Verwendung von Modellbau-Servos

Übung

a)

  • Vollziehen Sie das folgende Arduino-Programme "Sweep" nach.
  • Passen Sie die Schaltung und das Programm an den Arduino-Micro an und testen diese.
https://www.arduino.cc/en/Tutorial/Sweep

b)

Für den kompletten Sweep wird loop nur ein einziges mal aufgerufen. Dies würde ggf. die parallele Abarbeitung anderer Programmteile blockieren. Ändern Sie Sweep so, dass pro Winkelschritt loop genau einmal aufgerufen wird, indem Sie Zählvariablen außerhalb von loop einführen.

c) (Gegenstand der Vorlesung)

Die Auflösung des PWM-Signal für Servos aus der Arduino-Library ist nicht die maximal mögliche. Unter Verwendung von Register-Befehlen, soll eine möglichst feine Auflösung für die Servowinkelschritte erreicht werden. Werfen Sie als Vorbereitung schon einmal einen Blick auf folgendes Kapitel:

40_Mikrocontroller/04_PWM

Suchen Sie im Datenblatt für den im Arduino-Micro verbauten Mikrocontroller das passende Kapitel über PWM-Erzeugung heraus.

  • 4 -- 17|04|2018 -- TUESDAY

Beispiellösung zur Verwendung des Timers1 für eine Servoansteuerung mit hoher Winkelauflösung:

45_Mikro17/04_Timer/02_Timer1_Servo

Problem bei Vorlesungslösung: doch Clear on rising edge und nicht Set on rising edge!

servotimer1.zip servotimer1.zip -- Entwurf aus letzter Vorlesung.
#include <Servo.h>

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0;    // variable to store the servo position

void setup() {
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
}

void loop() {
  if(pos < 181)
  {
    myservo.write(pos);
    delay(15);
    pos += 1;
  }
  else if(pos > 180 and pos < 360)
  {
    myservo.write(360 - pos);
    delay(15);
    pos += 1;
  }
  else pos = 0;
}

Code 0-1: Studentische Lösung "sweep" ohne Blockierung der Loop-Schleife.

  • 5 -- 24|04|2018 -- TUESDAY

Die serielle Schnittstelle

Um sich Klarheit über das Funktionieren eines Mikrocontrollerprogramms zu verschaffen, ist es sehr nützlich Daten zwischen PC und Mikrocontroller auszutauschen.

Hierzu steht in der Arduino IDE der Serial-Monitor zur Verfügung.

Übung 1

Sehen Sie sich die folgenden Beispiele zur Verwendung der seriellen Schnittstelle mit dem Arduino an und testen sie und passen Sie die Programme nötigenfalls an den Arduino Micro an:

Arduino sendet: https://www.arduino.cc/en/Serial/Write
Arduino empfängt vom PC: https://www.arduino.cc/reference/en/language/functions/communication/serial/read/
Analog Read für IR-Sharp-Entfernungssensor: http://www.instructables.com/id/How-to-Use-the-Sharp-IR-Sensor-GP2Y0A41SK0F-Arduin/
Übung 2

Entwickeln Sie ein Arduino-Programm, bei dem über Befehle, die am PC im seriellen Monitor eingegeben werden, drei LEDs einzeln an- bzw. ausgeschaltet werden können.

b) Es wird ein Bitmuster für 8 LEDs übergeben: 01101001 (Beispiel). 1==korrespondierende LED an, sonst aus.

Übung 3

Analysieren Sie das folgende Programm:

96_Arduino/13_Motor_PWM2_seriell

Versuchen Sie auf dieser Grundlage ein Arduino-Programm zu schreiben, mit dem sich über den seriellen Monitor der Winkel eines Servos einstellen läßt.

Vorlesung

Einführung in Bussysteme:

40_Mikrocontroller/06_UART
  • 6 -- 15|05|2018 -- TUESDAY

Objektorientierte Programmierung auf dem Arduino

siehe:

96_Arduino/24_OOP
Übung 1

Schreiben Sie eine Klasse LED. Mit ihrer Hilfe soll eine LED bei PB7 an und ausgeschaltet werden können.

Es sollen nur Registerbefehle benutzt werden. Nicht betroffene Bits dürfen nicht beeinflußt werden.

Eine Instanz dieser Klasse soll folgede Objektmethoden besitzen:

  • ein()
  • aus()
Übung 2

Entwickeln Sie eine Klasse Servo1, die ein Servo-Objekt auf der Grundlage von Timer 1 bereitstellt.

Prozedurale Variante als Grundlage siehe hier:

45_Mikro17/04_Timer/02_Timer1_Servo

Eine Instanz dieser Klasse sollte folgende Objektmethoden besitzen:

  • setzeWinkel1(grad)
  • setzeWinkel2(grad)
Musterlösung zu Übung 2 (nicht ganz exakt nach Aufgabenstellung)

Die Lösung wurde in mehreren Stufen erarbeitet, die in den Sketchen ServoOOP1 bis ServoOOP4 ihren Niederschlag gefunden haben.

96_Arduino/30_day_by_day/ServoOOP.zip
  • 7 -- 22|05|2018 -- TUESDAY
Übung -- Verbindung von Processing und Arduino und OOP

Sowohl Arduino, als auch Processing bieten die Möglichkeit, eine serielle Schnittstelle zu benutzen.

Versuchen Sie ein Projekt zu realisieren, bei dem unter Processing ein Schieberegler programmiert wird und am Arduino-Micro ein Servo. Mit dem Schieberegler soll der Servo-Winkel zwischen 0 und 180 Grad einstellbar sein.

Fassen Sie sowohl die Processing-seitige Funktionalität, als auch die Arduino-seitige Funktionalität jeweils in eine Klasse zusammen und bereiten Sie das Endergebnis so auf, dass es möglichst einfach von anderen benutzt werden kann.

Was sollte man die die Klassen packen, was nicht, damit man die Klassen auch für andere Anwendungen einsetzen kann?

float x,y;
float xoff = 100;
float yoff = 100;
float breite = 300;
float hoehe  = 50;
float pos    = 0.5;
public void setup()
{
    size(700,700);
    frameRate(30);
}

public void draw()
{
    background(0);
    fill(0,0,255);
    rect(xoff,yoff,breite,hoehe);
    float x_anfasser = xoff + pos*breite;
    fill(255,0,0);
    ellipse(x_anfasser,yoff+hoehe/2,hoehe/4,hoehe);
}

public void mouseDragged()
{
    x = mouseX;
    y = mouseY;
    
    if(x>xoff && x<xoff+breite && y>yoff && y<yoff+hoehe)
    {
        pos = (x-xoff)/breite;
    }
}

Code 0-2: Processing-Beispiel selbst geschriebener Schieberegler (pos=0..1)

Prozeduraler Vorversuch

Möglichst einfache Umsetzung der Aufgabe als Test:

  • Zunächst keine OOP
  • Verwendung der verfügbaren Libraries bei Arduino und Processing
  • Umwandlung eines einzelnen ASCII-Zeichens in eine Wert. Dadurch nur Auflösung 2 Grad.
import processing.serial.*;

Serial myPort;  
int val;      

float x,y;
float xoff = 100;
float yoff = 100;
float breite = 300;
float hoehe  = 50;
float pos    = 0.5;
public void setup()
{
    size(700,700);
    frameRate(30);
    myPort = new Serial(this, "/dev/ttyACM0", 9600);
}
public void draw()
{
    background(0);
    fill(0,0,255);
    rect(xoff,yoff,breite,hoehe);
    float x_anfasser = xoff + pos*breite;
    fill(255,0,0);
    ellipse(x_anfasser,yoff+hoehe/2,hoehe/4,hoehe);
}
public void mouseDragged()
{
    x = mouseX;
    y = mouseY;
    
    if(x>xoff && x<xoff+breite && y>yoff && y<yoff+hoehe)
    {
        pos = (x-xoff)/breite;
        myPort.write((char)(33.0+pos*90.0));
    }
    
}

Code 0-3: Processing-Programm: Schieberegler und serielles Senden.

#include <Servo.h>

Servo myservo;  // create servo object to control a servo

int pos = 0;
int zeichen;
void setup() 
{
  // put your setup code here, to run once:
   myservo.attach(9);
   Serial.begin(9600);
}

void loop() 
{
    if (Serial.available() > 0) 
    {
         // read the incoming byte:
         zeichen = Serial.read();
         myservo.write((zeichen - 33)*2);
    }
}

Code 0-4: Arduino-Seite: Empfangen eines Zeichens, Umwandeln in einen Servo-Winkel

  • 8 -- 29|05|2018 -- TUESDAY

Verwendung eines MPU6050 Beschleunigungssensors

Der MPU6050 vereinigt einen dreiachsigen Beschleunigungssensor und einen dreiachsiges Gyroskopsensor. Er findet Anwendung in mobilen Devices, steht aber auch für die Verwendung mit Arduino auf kleinen Zusatzplatinen zur Verfügung. Er kann über den I2C-Bus angesprochen und ausgelesen werden.

Bei allen nachfolgenden Anwendungen wird die Platine wie folgt an den Arduino angeschlossen:


MPU6050 ---- Arduino

VCC     ---- 3.3V
GND     ---- GND
SCL     ---- SCL
SDA     ---- SDA


Code 0-5: Verbindung MPU6050 mit Arduino

Übung

1) Löten Sie an eine MPU6050-Platine eine Stiftleiste mit vier Pins. Die Leiste wird von unten angesteckt und auf der Bestückungsseite (oben) fest gelötet. Schauen Sie sich dazu das Kapitel "Löttechnik an":

73_COACH3/06_Layouting/04_Loettechnik/index.php

2) Verbinden Sie Arduino und MPU6050

3) Prüfen Sie mit Hilfe des folgenden Testprogramms, ob die Schaltung funktioniert: Ergründen Sie insbesondere die Wirkung der Orientierung der Platine auf die Ausgabe im seriellen Monitor.

#include<math.h>
#include<Wire.h>

//MPU6050:
const int MPU=0x68;  // I2C address of the MPU-6050
int16_t AcX,AcY,AcZ;
int x,y,z;

void setup() 
{
    //MPU6050
    Wire.begin();
    Wire.beginTransmission(MPU);
    Wire.write(0x6B);  // PWR_MGMT_1 register
    Wire.write(0);     // set to zero (wakes up the MPU-6050)
    Wire.endTransmission(true);  
    Serial.begin(9600);
}

void loop() 
{
     // put your main code here, to run repeatedly:
     Wire.beginTransmission(MPU);
     Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
     Wire.endTransmission(false);
     Wire.requestFrom(MPU,6,true);  // request a total of 14 registers
     AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)     
     AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
     AcZ=Wire.read()<<8|Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)

     x = (AcX/163);
     if(x>100) x=100;
     if(x<-100) x=-100;

     y = (AcY/163);
     if(y>100) y=100;
     if(y<-100) y=-100;

     z = (AcZ/163);
     if(z>100) z=100;
     if(z<-100) z=-100;

     Serial.print(x);
     Serial.print(" ");
     Serial.print(y);
     Serial.print(" ");
     Serial.println(z);

     delay(200);
}

Code 0-6: MPU6050 testen.

4) Schauen Sie sich die Theorie zum I2C-Bus an, sowie die Test-Software zu dem Einachser, der auch den MPU6050 benutzt:

40_Mikrocontroller/06_UART/01_Bussysteme/index.php
72_COACH2/05_I2C/index.php
15_Einachser/02_Bauanleitung/09_Testsoftware/index.php
https://playground.arduino.cc/Main/MPU-6050
https://www.mschoeffler.de/2017/10/05/tutorial-how-to-use-the-gy-521-module-mpu-6050-breakout-board-with-the-arduino-uno/

5) Überlegen Sie sich eine Anwendung mit dem MPU6050 und setzen diese um. Anregungen:

  • Orientierung zur Erdgravitation mittels farbiger LEDs anzeigen.
  • Servos über den MPU6050 steuern.
  • Tonhöhen steuern.
LED STRIP / SNAKE
ledstrip.zip -- Testprogramme.
https://github.com/pololu/pololu-led-strip-arduino/blob/master/README.md