Day by Day
(EN google-translate)
(PL google-translate)
Verzeichnis der im Verlauf des Semesters behandelten Themen
Donnerstag 18.03.2021
|
Links zu den passenden Inhalten auf kramann.info:
40_Mikrocontroller/01_Einfuehrung/02_Maschinensprache
40_Mikrocontroller/01_Einfuehrung/03_Assemblerbeispiel
45_Mikro17/02_ArduinoMicro
45_Mikro17/02_ArduinoMicro/01_Lauflicht
45_Mikro17/02_ArduinoMicro/02_Taster
atmel-7766-8-bit-avr-atmega16u4-32u4_datasheet.pdf
"Saal"-übung 1: Ampel
void setup() { pinMode(8, OUTPUT); pinMode(10, OUTPUT); pinMode(12, OUTPUT); digitalWrite(8, HIGH); digitalWrite(10, HIGH); digitalWrite(12, HIGH); } void loop() { }
Code 0-1: ampel1: erst einmal alle LEDs leuchten lassen.
void setup() { pinMode(8, OUTPUT); pinMode(10, OUTPUT); pinMode(12, OUTPUT); digitalWrite(8, HIGH); digitalWrite(10, HIGH); digitalWrite(12, HIGH); } void loop() { // Phase1: rot digitalWrite(8, HIGH); //rot AN digitalWrite(10, LOW); //gelb AUS digitalWrite(12, LOW); //grün AUS delay (2000); // Phase2: rot + gelb digitalWrite(8, HIGH); //rot AN digitalWrite(10, HIGH); //gelb AN digitalWrite(12, LOW); //grün AUS delay (2000); // Phase3: grün digitalWrite(8,LOW); //rot AUS digitalWrite(10, LOW); //gelb AUS digitalWrite(12, HIGH); //grün AN delay (2000); // Phase4: gelb digitalWrite(8,LOW); //rot AUS digitalWrite(10, HIGH); //gelb An digitalWrite(12, LOW); //grün Aus delay (2000); }
Code 0-2: ampel2: jetzt Zeitsteuerung hinzufügen.
"Saal"-übung 2: Fußgängerampel
void setup() { pinMode(8, OUTPUT); pinMode(10, OUTPUT); pinMode(12, INPUT); //digitalWrite(12, HIGH); //aktivieren des Pullupwiderstandes! digitalWrite(12, INPUT_PULLUP); } void loop() { // Phase1: rot digitalWrite(8, HIGH); //rot AN digitalWrite(10, LOW); //grün AUS if(digitalRead(12) == LOW) { digitalWrite(8, LOW); //rot AUS digitalWrite(10, HIGH); //grün AN delay(5000); } }
Code 0-3: neu hier: Reagieren auf Tastendruck.
Donnerstag 25.03.2021
|
Wenn Sie die Hardware haben, sollten Sie die Arduino IDE (Entwicklungsumgebung) installieren und ein erstes Beispielprojekt erstellen und sehen, ob es sich auf den Arduino-Micro übertragen läßt.
|
void setup() { Serial.begin(9600); } int x=0; void loop() { Serial.write(x+65); Serial.write("\n"); delay(1000); x++; x%=20; }
Code 0-4: Dies ist der Test-Quelltext, der im Video erstellt und verwendet wurde. Er schickt Zeichen an den PC, die im Serial Monitor der IDE angeschaut werden können.
Es folgen die Videos (als "nicht gelistet" auf youtube hochgealden und mit OBS-Studio erstellt):
Teil1 Um was geht es in den Videos?: https://youtu.be/hirAbmhThvA
Teil2 Download und Installation der Arduino IDE: https://youtu.be/BxzIk0RVjCc
Teil3 Erstellen, kompilieren und übertragen eines ersten Programms: https://youtu.be/s9a2o1YyruY
Donnerstag 08.04.2021
Teil 1 (praktischer Teil):
|
Wer findet den Port, von dem alle 8-Bit beim Arduino-Micro herausgeführt sind?
96_Arduino -- siehe Bild 0-2: Pinzuordnung zwischen Chip und Board.
Übung 1: Bauen Sie auf Ihrem Board die Schaltung hier unter Verwendung einzelner LEDs auf:
96_Arduino/22_Universal/02_LED_Leiste -- siehe Bild 0-1: Anschlußplan der LED-Leiste.
Übung 2: Programmieren Sie ein Lauflicht mit Hilfe der Programmiersprachelemente, die Sie bisher kennen.
Hinweise zu Übung 2:
|
void setup() { pinMode(17,OUTPUT); //PB0 pinMode(15,OUTPUT); //PB1 pinMode(16,OUTPUT); //PB2 pinMode(14,OUTPUT); //PB3 pinMode(8,OUTPUT); //PB4 pinMode(9,OUTPUT); //PB5 pinMode(10,OUTPUT);//PB6 pinMode(11,OUTPUT);//PB7 } void loop() { digitalWrite(17,HIGH); digitalWrite(15,LOW); digitalWrite(16,LOW); digitalWrite(14,LOW); digitalWrite(8,LOW); digitalWrite(9,LOW); digitalWrite(10,LOW); digitalWrite(11,LOW); delay(200); digitalWrite(17,LOW); digitalWrite(15,HIGH); digitalWrite(16,LOW); digitalWrite(14,LOW); digitalWrite(8,LOW); digitalWrite(9,LOW); digitalWrite(10,LOW); digitalWrite(11,LOW); delay(200); digitalWrite(17,LOW); digitalWrite(15,LOW); digitalWrite(16,HIGH); digitalWrite(14,LOW); digitalWrite(8,LOW); digitalWrite(9,LOW); digitalWrite(10,LOW); digitalWrite(11,LOW); delay(200); digitalWrite(17,LOW); digitalWrite(15,LOW); digitalWrite(16,LOW); digitalWrite(14,HIGH); digitalWrite(8,LOW); digitalWrite(9,LOW); digitalWrite(10,LOW); digitalWrite(11,LOW); delay(200); digitalWrite(17,LOW); digitalWrite(15,LOW); digitalWrite(16,LOW); digitalWrite(14,LOW); digitalWrite(8,HIGH); digitalWrite(9,LOW); digitalWrite(10,LOW); digitalWrite(11,LOW); delay(200); digitalWrite(17,LOW); digitalWrite(15,LOW); digitalWrite(16,LOW); digitalWrite(14,LOW); digitalWrite(8,LOW); digitalWrite(9,HIGH); digitalWrite(10,LOW); digitalWrite(11,LOW); delay(200); digitalWrite(17,LOW); digitalWrite(15,LOW); digitalWrite(16,LOW); digitalWrite(14,LOW); digitalWrite(8,LOW); digitalWrite(9,LOW); digitalWrite(10,HIGH); digitalWrite(11,LOW); delay(200); digitalWrite(17,LOW); digitalWrite(15,LOW); digitalWrite(16,LOW); digitalWrite(14,LOW); digitalWrite(8,LOW); digitalWrite(9,LOW); digitalWrite(10,LOW); digitalWrite(11,HIGH); delay(200); }
Code 0-5: Musterlösung zum Lauflicht.
Teil 2 (theoretischer Teil):
|
Konventionen bei der Namensgebung für Funktionen, Klassen, Objekten und Variablen
https://de.wikipedia.org/wiki/Binnenmajuskel (studentischer Hinweis)Lösungsvarianten
lauflicht1 -- konservative Variante
void setup() { pinMode(17,OUTPUT); //PB0 pinMode(15,OUTPUT); //PB1 pinMode(16,OUTPUT); //PB2 pinMode(14,OUTPUT); //PB3 pinMode(8,OUTPUT); //PB4 pinMode(9,OUTPUT); //PB5 pinMode(10,OUTPUT);//PB6 pinMode(11,OUTPUT);//PB7 } void loop() { digitalWrite(17,HIGH); digitalWrite(15,LOW); digitalWrite(16,LOW); digitalWrite(14,LOW); digitalWrite(8,LOW); digitalWrite(9,LOW); digitalWrite(10,LOW); digitalWrite(11,LOW); delay(200); digitalWrite(17,LOW); digitalWrite(15,HIGH); digitalWrite(16,LOW); digitalWrite(14,LOW); digitalWrite(8,LOW); digitalWrite(9,LOW); digitalWrite(10,LOW); digitalWrite(11,LOW); delay(200); digitalWrite(17,LOW); digitalWrite(15,LOW); digitalWrite(16,HIGH); digitalWrite(14,LOW); digitalWrite(8,LOW); digitalWrite(9,LOW); digitalWrite(10,LOW); digitalWrite(11,LOW); delay(200); digitalWrite(17,LOW); digitalWrite(15,LOW); digitalWrite(16,LOW); digitalWrite(14,HIGH); digitalWrite(8,LOW); digitalWrite(9,LOW); digitalWrite(10,LOW); digitalWrite(11,LOW); delay(200); digitalWrite(17,LOW); digitalWrite(15,LOW); digitalWrite(16,LOW); digitalWrite(14,LOW); digitalWrite(8,HIGH); digitalWrite(9,LOW); digitalWrite(10,LOW); digitalWrite(11,LOW); delay(200); digitalWrite(17,LOW); digitalWrite(15,LOW); digitalWrite(16,LOW); digitalWrite(14,LOW); digitalWrite(8,LOW); digitalWrite(9,HIGH); digitalWrite(10,LOW); digitalWrite(11,LOW); delay(200); digitalWrite(17,LOW); digitalWrite(15,LOW); digitalWrite(16,LOW); digitalWrite(14,LOW); digitalWrite(8,LOW); digitalWrite(9,LOW); digitalWrite(10,HIGH); digitalWrite(11,LOW); delay(200); digitalWrite(17,LOW); digitalWrite(15,LOW); digitalWrite(16,LOW); digitalWrite(14,LOW); digitalWrite(8,LOW); digitalWrite(9,LOW); digitalWrite(10,LOW); digitalWrite(11,HIGH); delay(200); }
Code 0-6: lauflicht1
lauflicht2 -- Array verwenden
void setup() { pinMode(17,OUTPUT); //PB0 pinMode(15,OUTPUT); //PB1 pinMode(16,OUTPUT); //PB2 pinMode(14,OUTPUT); //PB3 pinMode(8,OUTPUT); //PB4 pinMode(9,OUTPUT); //PB5 pinMode(10,OUTPUT);//PB6 pinMode(11,OUTPUT);//PB7 } int arr[] = {17,15,16,14,8,9,10,11}; int index = 0; void loop() { //alle aus: for(int i=0;i<8;i++) { digitalWrite(arr[i],LOW); } //aktueller an: digitalWrite(arr[index],HIGH); delay(200); index++; if(index==8) index=0; //index%=8; // Alternative zu if(..).. }
Code 0-7: lauflicht2
lauflicht3 -- Funktionen verwenden
void setup() { pinMode(17,OUTPUT); //PB0 pinMode(15,OUTPUT); //PB1 pinMode(16,OUTPUT); //PB2 pinMode(14,OUTPUT); //PB3 pinMode(8,OUTPUT); //PB4 pinMode(9,OUTPUT); //PB5 pinMode(10,OUTPUT);//PB6 pinMode(11,OUTPUT);//PB7 } int arr[] = {17,15,16,14,8,9,10,11}; int index = 0; void alleAus() { //alle aus: for(int i=0;i<8;i++) { digitalWrite(arr[i],LOW); } } void einschalten(int nummer) { digitalWrite(arr[nummer],HIGH); } void loop() { alleAus(); //aktueller an: einschalten(index); delay(200); index++; if(index==8) index=0; //index%=8; // Alternative zu if(..).. }
Code 0-8: lauflicht3
lauflicht4 -- Register
void setup() { DDRB = 0b11111111; } int x = 1; void loop() { // 1 dezimal => 0b00000001 // 2 dezimal => 0b00000010 // 4 dezimal => 0b00000100 PORTB = x; x*=2; // erzeugt 1 2 4 8 16 32 64 128, dann wieder 1 2 ... if(x>=256) x = 1; delay(200); }
Code 0-9: lauflicht4
lauflicht5 -- Bitshift-Operation
void setup() { DDRB = 0b11111111; // PB3 deaktiviert !!!! } unsigned char x = 0; void loop() { // 1 dezimal => 0b00000001 // 2 dezimal => 0b00000010 // 4 dezimal => 0b00000100 PORTB = (1<<x); // schiebe die 1 x-mal nach links. x++; x%=8; //Restdivision, liefert ganzzahligen Rest. // identisch mit x=x%8;, liefert 0 1 2 3 4 5 6 7 0 1 2... delay(200); }
Code 0-10: lauflicht5
Donnerstag 15.04.2021
Themen
|
45_Mikro17/03_DigitalIO/01_Elektrische_Eigenschaften
45_Mikro17/03_DigitalIO/02_Pullup_Widerstaende
45_Mikro17/03_DigitalIO/03_Bitmasken_Eingang
45_Mikro17/03_DigitalIO/04_Bitmasken_Ausgang
Übung
Steuerbares Lauflicht, quasi Kreativaufgabe.
Für alle nachfolgenden Programmieraufgaben sind Register und Bitshiftoperationen einzusetzen.
|
DDRB = 0b11111111; PORTB = 0b00000001; //PORTD komplett als Eingang konfigurieren: DDRD = 0b00000000; //Alle Pullupwiderstände aktivieren für PORTD: PORTD = 0b11111111; } void loop() { //Eingangsbyte mit Bitmaske verknüpfen und //je nach Ergebnis Lauflicht laufen lassen: if( (PIND & 0b00000001)==0 ) { PORTB = (PORTB>>7) | (PORTB<<1); } else { PORTB = (PORTB>>1) | (PORTB<<7); } delay(500); }
Code 0-11: Beispiel für ein Lauflicht mit Richtungssteuerung
Donnerstag 22.04.2021
Themen
|
Links zum Thema
https://www.arduino.cc/reference/en/language/functions/communication/serial/
https://www.arduino.cc/reference/de/language/functions/communication/serial/begin/
45_Mikro17/05_OOP/02_OOP_ATmega32/04_Datentypen
Übung
Die Lauflichtsteuerung soll nun nicht mehr über die Schalter erfolgen, sondern durch Tippen von Ziffern auf der PC-Tastatur.
https://content.arduino.cc/assets/Pinout-Micro_latest.png -- besseres Pin-Layout
//Rotieren realisieren unsigned int arr[] = {0b1111111100000000, 0b1000000010000000, 0b1010101010101010}; unsigned int auswahl = 0; void setup() { DDRB = 0b11111111; Serial.begin(9600); } void loop() { if(Serial.available()) { auswahl = arr[Serial.read()%3]; } auswahl = ((auswahl << 1) | (auswahl >> 15)) ; PORTB = auswahl; delay(200); }
Code 0-12: Lauflicht, bei dem über die serielle Schnittstelle unter drei Mustern gewählt werden kann.
Donnerstag 29.04.2021
Themen
|
Übung: Längeres Projekt, an dessen Ende eine Digitaluhr steht
Teilübungen
|
Bild 0-1: Übersicht zu LTC-2723WC
Datenblatt zu Atmega32u4: Atmel-7766-8-bit-AVR-ATmega16U4-32U4_Datasheet.pdf
int zahl = 0; unsigned char pattern[] = { // ABCDEFGP 0b11111100, // 0 0b01100000, // 1 0b11011010, // 2 0b11110010, // 3 0b01100110, // 4 0b10110110, // 5 0b10111110, // 6 0b11100000, // 7 0b11111110, // 8 0b11110110, // 9 0b11000000, // dp }; void show(int ziffer, int digit) { digitalWrite(0,HIGH); digitalWrite(1,HIGH); digitalWrite(2,HIGH); digitalWrite(3,HIGH); digitalWrite(4,HIGH); digitalWrite(digit,LOW); PORTB = pattern[ziffer]; } void setup() { pinMode(0,OUTPUT); pinMode(1,OUTPUT); pinMode(2,OUTPUT); pinMode(3,OUTPUT); pinMode(4,OUTPUT); digitalWrite(0,HIGH); digitalWrite(1,HIGH); digitalWrite(2,HIGH); digitalWrite(3,HIGH); digitalWrite(4,HIGH); DDRB=255; PORTB=0; Serial.begin(9600); } void loop() { zahl++; zahl%=10; Serial.write(zahl+48); show(zahl,4); delay(1000); }
Code 0-13: Quelltext 1. Teilübung: zyklisch 0..9 zählen
int zahl = 0; int MAX = 60*24; int DIGIT[]={0,0,0,0,0}; unsigned char pattern[] = { // ABCDEFGP 0b11111100, // 0 0b01100000, // 1 0b11011010, // 2 0b11110010, // 3 0b01100110, // 4 0b10110110, // 5 0b10111110, // 6 0b11100000, // 7 0b11111110, // 8 0b11110110, // 9 0b11000000, // dp }; void show(int ziffer, int digit) { digitalWrite(0,HIGH); digitalWrite(1,HIGH); digitalWrite(2,HIGH); digitalWrite(3,HIGH); digitalWrite(4,HIGH); digitalWrite(digit,LOW); PORTB = pattern[ziffer]; } void setup() { pinMode(0,OUTPUT); pinMode(1,OUTPUT); pinMode(2,OUTPUT); pinMode(3,OUTPUT); pinMode(4,OUTPUT); digitalWrite(0,HIGH); digitalWrite(1,HIGH); digitalWrite(2,HIGH); digitalWrite(3,HIGH); digitalWrite(4,HIGH); DDRB=255; PORTB=0; Serial.begin(9600); } int auffrischen = 0; void loop() { if(auffrischen>=200) { DIGIT[0] = 10; DIGIT[1] = (zahl/60)/10; DIGIT[2] = (zahl/60)%10; DIGIT[3] = (zahl%60)/10; DIGIT[4] = (zahl%60)%10; zahl++; zahl%=MAX; Serial.write(zahl+48); auffrischen=0; } show(DIGIT[auffrischen%5],auffrischen%5); delay(5); auffrischen++; }
Code 0-14: Quelltext 2.: Uhr, die jede Sekunde eine Minute hochzählt
Donnerstag 06.05.2021
Themen
|
Datenblatt passend zu Mikrocontroller auf Arduino Micro: Atmel-7766-8-bit-AVR-ATmega16U4-32U4_Datasheet.pdf
Übung
|
|
Übung: Was ist eine ISR == Interrupt Service Routine?
Beispiel siehe: "Zusatz-LED bei Digital-Pin 12 durch Interrupt-Routine gesteuert " in Arduino/15_Scheduler.
|
Donnerstag 20.04.2021
Themen
|
Timer als "Timer" (Quarz genauer Zähler)
Beispiel: Quarz genaue Ansteuerung einer LED. Sie soll mit 2Hz "aufblitzen"
Bild 0-2: Register TCCR1A (S.131 Datenblatt)
Bild 0-3: Übersichtstabelle (S.133 Datenblatt) zu den einzelnen Modes von Timer 1 und 3. Mode 12: CTC-Mode "Clear Time on Compare Match".
Bild 0-4: Übersichtstabelle (S.134 Datenblatt) zu den möglichen Vorteilungen des Quarztaktes.
Bild 0-5: Betrifft (S.137) "TIMSK1"
void setup() { TCCR1B |= (1<<WGM13); //Mode 12 TCCR1B |= (1<<WGM12); //Setzen eines Bits TCCR1A &= ~(1<<WGM11); //Löschen eines Bits TCCR1A &= ~(1<<WGM10); //CS=100, 16000000 / 256 = 62500Hz TCCR1B |= (1<<CS12); TCCR1B &= ~(1<<CS11); TCCR1B &= ~(1<<CS10); ICR1=31250; //2Hz, benötigt eine halbe Sekunde bis dort hoch zu zählen TIMSK1 |= (1<<ICIE1); //Mode 12, dass ICR1 als Zählobergrenze genutzt wird. pinMode(2,OUTPUT); } void loop() { //Zeitsteuerung durch Auslesen des Zählerstandes: if(TCNT1<2000) //"Aufblitzen" digitalWrite(2,1); else //sonst aus. digitalWrite(2,0); }
Code 0-15: Blitz-LED.
Bild 0-6: ArduinoMicro Pinlayout
Bild 0-7: Testaufbau zur "Blitz-LED".
ISR Interrupt-Service-Routine
Umsetzung des vorangehenden Beispiels mit einer Interrupt-Service-Routine (ISR).
|
#include<avr/interrupt.h> volatile bool ZUSTAND=false; //Interrupt-Service-Routine ISR(TIMER1_COMPA_vect) { //Zunächst nur Blinken von 1Hz umgesetzt! if(ZUSTAND) digitalWrite(2,ZUSTAND); else digitalWrite(2,ZUSTAND); ZUSTAND=!ZUSTAND; } void setup() { // TCCR1B |= (1<<WGM13); //Mode 12 TCCR1B &= ~(1<<WGM13); //Mode 4 TCCR1B |= (1<<WGM12); TCCR1A &= ~(1<<WGM11); TCCR1A &= ~(1<<WGM10); //CS=100, 16000000 / 256 = 62500Hz TCCR1B |= (1<<CS12); TCCR1B &= ~(1<<CS11); TCCR1B &= ~(1<<CS10); OCR1A=31250; //0,5Hz == 4 Schläge! // TIMSK1 |= (1<<ICIE1); //Mode 12 TIMSK1 |= (1<<OCIE1A); //Mode 4 sei(); //Aktivieren von Interrupts! pinMode(2,OUTPUT); } void loop() { //Frei für beliebigen anderen Code! }
Code 0-16: Blinken mit 1Hz mit ISR.
Aufbau wie zuvor.
Übung
|
Uhr mit ISR
#include<avr/interrupt.h> volatile bool ZUSTAND=false; //volatile bool = flüchtig-wechselhaft //Interrupt-Service-Routine ISR(TIMER1_COMPA_vect) { //Zunächst nur Blinken von 1Hz umgesetzt! if(ZUSTAND){ digitalWrite(2,ZUSTAND); OCR1A=1250; } else { digitalWrite(2,ZUSTAND); OCR1A=62250; } ZUSTAND=!ZUSTAND; } void setup() { // TCCR1B |= (1<<WGM13); //Mode 12 TCCR1B &= ~(1<<WGM13); //Mode 4 TCCR1B |= (1<<WGM12); TCCR1A &= ~(1<<WGM11); TCCR1A &= ~(1<<WGM10); //CS=100, 16000000 / 256 = 62500Hz TCCR1B |= (1<<CS12); TCCR1B &= ~(1<<CS11); TCCR1B &= ~(1<<CS10); OCR1A=31250; //0,5Hz == 4 Schläge! // TIMSK1 |= (1<<ICIE1); //Mode 12 TIMSK1 |= (1<<OCIE1A); //Mode 4 sei(); //Aktivieren von Interrupts! pinMode(2,OUTPUT); } void loop() { //Frei für beliebigen anderen Code! } //---- 2. Lösung ---- #include<avr/interrupt.h> volatile int ZUSTAND=0 ; //Interrupt-Service-Routine ISR(TIMER1_COMPA_vect) { if(ZUSTAND==0) digitalWrite(2,1); //LED else//sonst aus. digitalWrite(2,0); ZUSTAND++; if(ZUSTAND>9) { ZUSTAND = 0 ; } // ZUSTAND%=10 ; } void setup() { // TCCR1B |= (1<<WGM13); //Mode 12 TCCR1B &= ~(1<<WGM13); //Mode 4 TCCR1B |= (1<<WGM12); TCCR1A &= ~(1<<WGM11); TCCR1A &= ~(1<<WGM10); //CS=100, 16000000 / 256 = 62500Hz TCCR1B |= (1<<CS12); TCCR1B &= ~(1<<CS11); TCCR1B &= ~(1<<CS10); OCR1A=3125; // 0,05s // TIMSK1 |= (1<<ICIE1); //Mode 12 TIMSK1 |= (1<<OCIE1A); //Mode 4 sei(); //Aktivieren von Interrupts! pinMode(2,OUTPUT); } void loop() { //Frei für beliebigen anderen //Zeitsteuerung durch Auslesen des Zählerstandes: }
Code 0-17: Studentische Lösungen
Übung
Kombinieren Sie nun das zuvor Erarbeitete und das Uhr-Projekt, um die Uhr mittels ISR Quarz-genau zu machen.
PWM mit Arduino-Funktionen zum Dimmen einer LED.
//Dimmen einer LED mittels "analogWrite" void setup() { } int x=0; int y=0; void loop() { if(x<256) y=x; else y=511-x; analogWrite(9,y); x++; x%=512; delay(5); }
Code 0-18: Dimmen einer LED auf Digital-Pin9.
PWM mittels Register-Konfigurationen zum Dimmen einer LED.
|
Umsetzung als Übung:
Übung
|
Hilfestellung zum Verständnis der Servoansteuerung, siehe:
Bild 0-8: Notwendiges Zeitsignal zur Ansteuerung eines Servos.
PWM mit Arduino-Funktionen zum Ansteuern eines Modellbau-Servos.
Übung
|
PWM mittels Register-Konfigurationen zum Ansteuern eines Modellbau-Servos.
#define WMIN 1000 #define WMITTE 1500 #define WMAX 2000 #define SCHRITTE 1000 //Mode 8 //Phasen- und Frequenz-korrekt //WGM1 3 2 1 0 // 1 0 0 0 //ICR1=..... TOP //fpwm = fclk/(2*N*TOP) //Vorteilung //N=8 //80Hz = 16000000/(2*8*TOP) //TOP = 16000000/(2*8*80Hz)=12500 //dt==1000ms*(1/80Hz)/12500 == 0,001ms (1 Schritt == 0,001ms) //=> //1ms == 1000 Schritte //1,5ms == 1500 Schritte //2ms == 2000 Schritte void setup() { TCCR1A = (1<<COM1A1) | (0<<COM1A0) | (1<<COM1B1) | (0<<COM1B0) | (0<<COM1C1) | (0<<COM1C0) | (0<<WGM11) | (0<<WGM10); TCCR1B = (0<<ICNC1) | (0<<ICES1) | (1<<WGM13) | (0<<WGM12) | (0<<CS12) | (1<<CS11) | (0<<CS10); //Vort. 256, s.S. 125 ICR1=12500; DDRB |= (1<<PB5); //OCR1A DDRB |= (1<<PB6); //OCR1B OCR1A = WMITTE; //PWM-Breite auf Mitte setzen. OCR1B = WMITTE; //PWM-Breite auf Mitte setzen. } void loop() { OCR1A = WMAX; //PWM-Breite auf Null setzen. OCR1B = WMAX; //PWM-Breite auf Null setzen. delay(3000); OCR1A = WMITTE; //PWM-Breite auf Null setzen. OCR1B = WMITTE; //PWM-Breite auf Null setzen. delay(3000); OCR1A = WMIN; //PWM-Breite auf Null setzen. OCR1B = WMIN; //PWM-Breite auf Null setzen. delay(3000); }
Code 0-19: Modellbau-Servos auf OC1A und OC1B mittels Timer 1 mit hoher Genauigkeit ansteuern.
Bild 0-9: Dateneingang (orange oder gelb) des Servos ist gemeinsam mit der LED an Digital-Pin9 angeschlossen. Stromversogung des Servos: braun=Ground(Masse), rot=+5Volt.
Donnerstag 03.06.2021
WICHTIG: Gruppenaufteilung für Probe-E-Test festlegen!
Themen
|
|
zu OOP:
|
96_Arduino/24_OOP -- Prinzipielles Prinzip zur Verwendung von OOP in einem Arduino-Projekt.
Übung
|
OOP für einzelne Ziffer
class Ziffern { private: unsigned char pattern[11];// = public: void start() { pattern[0]=0b11111100; // 0 pattern[1]=0b01100000; // 1 pattern[2]=0b11011010; // 2 pattern[3]=0b11110010; // 3 pattern[4]=0b01100110; // 4 pattern[5]=0b10110110; // 5 pattern[6]=0b10111110; // 6 pattern[7]=0b11100000; // 7 pattern[8]=0b11111110; // 8 pattern[9]=0b11110110; // 9 pattern[10]=0b11000000; // dp pinMode(0,OUTPUT); pinMode(1,OUTPUT); pinMode(2,OUTPUT); pinMode(3,OUTPUT); pinMode(4,OUTPUT); digitalWrite(0,HIGH); digitalWrite(1,HIGH); digitalWrite(2,HIGH); digitalWrite(3,HIGH); digitalWrite(4,HIGH); DDRB=255; PORTB=0; } void show(int ziffer, int digit) { digitalWrite(0,HIGH); digitalWrite(1,HIGH); digitalWrite(2,HIGH); digitalWrite(3,HIGH); digitalWrite(4,HIGH); digitalWrite(digit,LOW); PORTB = pattern[ziffer]; } };
Code 0-20: Klasse Ziffern in File Ziffern.h
#include "Ziffern.h" Ziffern ziffern; int zahl = 0; void setup() { ziffern.start(); Serial.begin(9600); } void loop() { zahl++; zahl%=10; Serial.write(zahl+48); ziffern.show(zahl,4); delay(1000); }
Code 0-21: Hauptprogramm dazu
... Auffrischen von vier Ziffern:
class Ziffern { private: int digitindex; int z[4]; unsigned char pattern[11];// = public: void start() { digitindex=0; pattern[0]=0b11111100; // 0 pattern[1]=0b01100000; // 1 pattern[2]=0b11011010; // 2 pattern[3]=0b11110010; // 3 pattern[4]=0b01100110; // 4 pattern[5]=0b10110110; // 5 pattern[6]=0b10111110; // 6 pattern[7]=0b11100000; // 7 pattern[8]=0b11111110; // 8 pattern[9]=0b11110110; // 9 pattern[10]=0b11000000; // dp z[0] = pattern[0]; z[1] = pattern[1]; z[2] = pattern[2]; z[3] = pattern[3]; pinMode(0,OUTPUT); pinMode(1,OUTPUT); pinMode(2,OUTPUT); pinMode(3,OUTPUT); pinMode(4,OUTPUT); digitalWrite(0,HIGH); digitalWrite(1,HIGH); digitalWrite(2,HIGH); digitalWrite(3,HIGH); digitalWrite(4,HIGH); DDRB=255; PORTB=0; } void show(int ziffer, int digit) { z[digit] = pattern[ziffer]; /* digitalWrite(0,HIGH); digitalWrite(1,HIGH); digitalWrite(2,HIGH); digitalWrite(3,HIGH); digitalWrite(4,HIGH); digitalWrite(digit,LOW); PORTB = pattern[ziffer]; */ } void auffrischen() { digitalWrite(0,HIGH); digitalWrite(1,HIGH); digitalWrite(2,HIGH); digitalWrite(3,HIGH); digitalWrite(4,HIGH); if(digitindex<2) digitalWrite(digitindex,LOW); else digitalWrite(digitindex+1,LOW); PORTB = pattern[z[digitindex]]; digitindex++; digitindex%=4; } };
Code 0-22: Klasse Ziffern
#include "Ziffern.h" Ziffern ziffern; int zahl = 0; int ZZZ=0; void setup() { ziffern.start(); } void loop() { if(ZZZ>=100) { ZZZ=0; zahl++; zahl%=10000; ziffern.show(zahl%10,3); ziffern.show((zahl/10)%10,2); ziffern.show((zahl/100)%10,1); ziffern.show((zahl/1000)%10,0); } delay(1); ziffern.auffrischen(); ZZZ++; }
Code 0-23: Hauptprogramm
Studentische Musterlösung der Übung
#define WMIN1 1000 #define WMITTE1 1500 #define WMAX1 2000 #define SCHRITTE1 1000 #include "SERVO.h" SERVO servo; int winkel=-900; void setup() { servo.start(); } void loop() { servo.setWinkel((float)winkel*0.1); delay(10); winkel++; if(winkel>900) winkel=-900; } //#include "Arduino.h" class SERVO { private: int WMIN=1000; //Konstanten sollen möglichst mit Großbuchstaben geschrieben werden int WMITTE=1500; int WMAX=2000; int SCHRITTE=1000; //die Variablen können auch im Hauptprogramm außerhalb der Klasse bleiben public: void start() //Methoden sollen mit kleinen Buchstaben beginnen um sie von Klassen zu unterscheiden { TCCR1A = (1<<COM1A1) | (0<<COM1A0) | (1<<COM1B1) | (0<<COM1B0) | (0<<COM1C1) | (0<<COM1C0) | (0<<WGM11) | (0<<WGM10); TCCR1B = (0<<ICNC1) | (0<<ICES1) | (1<<WGM13) | (0<<WGM12) | (0<<CS12) | (1<<CS11) | (0<<CS10); //Vort. 256, s.S. 125 ICR1=12500; DDRB |= (1<<PB5); //OCR1A DDRB |= (1<<PB6); //OCR1B OCR1A = WMITTE; //PWM-Breite auf Mitte setzen. OCR1B = WMITTE; //PWM-Breite auf Mitte setzen. } void set (int wert) { OCR1A = wert; //PWM-Breite auf Null setzen. OCR1B = wert; //PWM-Breite auf Null setzen. } /* * wert= + - 45° */ void setWinkel (float wert) { wert=wert+45.0; //Bereich auf 0 bis 90 verschieben. wert=wert/90.0; //Bereich auf 0 bis 1 stauchen. wert=wert*1000.0; //Bereich dehnen auf 0 bis 1000. wert=wert+1000.0; //Bereich shiften nach 1000 bis 2000 OCR1A = (int)wert; //float wird in int umgewandelt OCR1B = (int)wert; } };
Code 0-24: Studentische Musterlösung Servo-Klasse.