# Arduino 22/23
Arduino ist eine freie Physical-Computing-Plattform, bestehend aus einem Mikrocontroller mit verschiedenen Ein- und Ausgängen sowie einer Entwicklungsumgebung, die es erlaubt den Mikrocontroller auf einfache Art und Weise zu programmieren. Mit Hilfe von weiterer Sensorik und Aktorik lassen sich hiermit verschiedenste Projekte umsetzen. Vom Wakeup-Light über Luftsensor bis hin zum Marmeladen-Drucker ist alles möglich.
In diesem Kurs werden die nötigen Grundlagen zur Realisierung von Schaltkreisen und zur Programmierung des Mikrocontrollers vermittelt, um anschließend eigene, kleine Projekte umzusetzen. Nach einer Einführung in Technik und Programmierung erarbeiten wir Konzepte für Minimalprodukte, welche auf diese reagieren und setzen sie mit Hilfe der Arduino-Plattform um.
## gemeinsamer Drive Ordner
Gemeinsamer Drive [Ordner](https://drive.google.com/drive/folders/11u4r4HAHy6-1WFv3yItzNPUD5BnqGwdr)
## Ressourcen
[Skript](https://docs.google.com/presentation/d/1WpHrZfxUw6V7VhWglJfUbLwFdTmapWLH3dLy8gEjGVc/edit?usp=sharing)
Arduino IDE für [MAC / LINUX / WIN](https://www.arduino.cc/en/software)
Arduino [Reference](https://www.arduino.cc/reference/de/)
[Basic Arduino Wissen](https://content.arduino.cc/assets/ArduinoComic-deutsch-PNG.pdf)
CH340 Treiber und Anleitung [link](https://sparks.gogo.co.nz/ch340.html)
[PWM](https://www.exp-tech.de/blog/arduino-tutorial-pulsweitenmodulation-pwm)
[Elektronik Kompendium](https://www.elektronik-kompendium.de/)
Grundlagen Elektronik [link](https://https://starthardware.org/grundlagen-spannung-strom-und-widerstand/)
Noch mehr Elektronikgrundlagen [link](https://starthardware.org/grundlagen-spannung-strom-und-widerstand/)
**Beispiele:**
* http://www.overtaxedsurface.de/#video
* https://vimeo.com/76479685
* Arduino Projects to Save the World [link](http://www.multimedialab.be/doc/erg/2017-2018/Arduino/Arduino_Projects_To_Save_The_World.pdf)
## 03.11.
Grundlage Programmieren und Hardware [link](https://docs.google.com/presentation/d/1WpHrZfxUw6V7VhWglJfUbLwFdTmapWLH3dLy8gEjGVc/edit?usp=sharing)
## 10.11
analogRead()
if Statement siehe Skript
### Hausaufgabe
Nachbau der Schaltung aus dem [Video](https://vimeo.com/76479685)
also ein Element ohne Hülle :-)
## 17.11
digitalRead() (Button)
for loop siehe Skript
### Hausaufgabe
Interaktion mit 2 Buttons :-)
## 24.11
Einführung PWM
LED dimmen
Potentiometer und Servo
## 15.12
[Neopixel](https://learn.adafruit.com/adafruit-neopixel-uberguide)
---
## Abschlussprojekte
## Projekttitel
Name
Beschreibung
Foto/Video
Hardware
Code
## NFC_KOFFER_LOCK
Christian Schmidt
Die Griffe des Koffers sind im normalzustand eingezogen, sodass der Koffer nicht von Fremden weggetragen werden kann. Sobald der Besitzer den Entschlüsselungsgegenstand (Ring; Personalausweis) über den Sensor hält, klappen die Griffe aus. Bei gültiger Entschlüsselung blinkt der Koffer grün auf. Bei ungültiger Entschlüsselung blinkt er rot auf.
[https://drive.google.com/file/d/1Zexv-zAD2_gwLl3G4kBjfNcBR-HYTQJf/view?usp=sharing]
NFC Sensor
NFC Tag Sticker
Magnetschloss
Relay
Neopixel LED
Arduino Uno
#include <SPI.h>
#include <MFRC522.h>
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif
#define SS_PIN 10
#define RST_PIN 9
#define LED_PIN 6
#define LED_COUNT 30
#define maximumBrightness 255
#define RELAY 3 //relay pin
#define ACCESS_DELAY 1000
#define DENIED_DELAY 1000
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance.
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
void setup()
{
Serial.begin(9600); // Initiate a serial communication
SPI.begin(); // Initiate SPI bus
mfrc522.PCD_Init(); // Initiate MFRC522
strip.begin();
strip.show();
pinMode(RELAY, OUTPUT);
digitalWrite(RELAY, LOW);
Serial.println("Put your card to the reader...");
Serial.println();
}
void loop()
{
// Look for new cards
if ( ! mfrc522.PICC_IsNewCardPresent())
{
return;
}
// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial())
{
return;
}
//Show UID on serial monitor
Serial.print("UID tag :");
String content= "";
byte letter;
for (byte i = 0; i < mfrc522.uid.size; i++)
{
Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
Serial.print(mfrc522.uid.uidByte[i], HEX);
content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
content.concat(String(mfrc522.uid.uidByte[i], HEX));
}
Serial.println();
Serial.print("Message : ");
content.toUpperCase();
if (content.substring(1) == "04 2B 39 3A D0 72 81") //change here the UID of the card/cards that you want to give access
{
Serial.println("Authorized access");
Serial.println();
delay(500);
digitalWrite(RELAY, HIGH);
delay(ACCESS_DELAY);
digitalWrite(RELAY, LOW);
for (int i = 0; i < LED_COUNT; i++) {
strip.setPixelColor(i, 0, 127, 0);
}
strip.show();
delay(1000);
for (int i = 0; i < LED_COUNT; i++) {
strip.setPixelColor(i, 0, 0, 0);
}
strip.show();
delay(500);
}
else {
Serial.println(" Access denied");
delay(DENIED_DELAY);
for (int i = 0; i < LED_COUNT; i++) {
strip.setPixelColor(i,127, 0, 0);
}
strip.show();
delay(1000);
for (int i = 0; i < LED_COUNT; i++) {
strip.setPixelColor(i, 0, 0, 0);
}
strip.show();
delay(500);
}
strip.show();
}
## wütend Schalter
Shuang Chen
Wenn jemand an die Tür kommt und das Licht nicht ausgeschaltet hat (ohne Veränderung des Lichtzustands), dann erfolgt eine Interaktion: das Licht leuchtet rot auf und es ertönt ein wütender Schrei.
Dieser Code liest die Entfernung von einem HC-SR04 Ultraschall-Abstandssensor und die Lichtintensität von einem Lichtabhängigen Widerstand (LDR) ein und steuert dann einen Neopixel LED-Streifen entsprechend.Wenn eine Person zur Tür kommt und das Licht nicht ausgeschaltet hat, wird der Neopixel-Streifen rot und ein wütender Ton wird über einen Piezo-Summer abgespielt.Die Tonfrequenz und Dauer variieren abhängig von der gemessenen Entfernung zur Person, wobei eine größere Entfernung zu einem höheren Ton führt.
**video**
https://drive.google.com/file/d/1bx94lwDCn08jKijcuCt2JC6rGMaBhaT5/view?usp=share_link

**code:**
```
#include <Adafruit_NeoPixel.h>
#define LED_PIN 6
#define LED_COUNT 7
#define TRIG_PIN 13
#define ECHO_PIN 12
#define LIGHT_PIN A0
#define BUZZER_PIN 10
#define MAX_DISTANCE 200
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
Serial.begin(9600);
strip.begin();
strip.show();
strip.setBrightness(200);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(LIGHT_PIN, INPUT);
pinMode(BUZZER_PIN, OUTPUT);
}
void loop() {
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
long duration = pulseIn(ECHO_PIN, HIGH);
int distance = duration * 0.034 / 2;
distance = min(distance, MAX_DISTANCE);
Serial.print("Distance: ");
Serial.print(distance);
Serial.println(" cm");
int lightLevel = analogRead(LIGHT_PIN);
Serial.print("Light level: ");
Serial.println(lightLevel);
int frequency = map(distance, 0, MAX_DISTANCE, 100, 1000);
int durationMs = map(distance, 0, MAX_DISTANCE, 100, 500);
tone(BUZZER_PIN, frequency, durationMs);
for(int i=0; i<strip.numPixels(); i++) {
int brightness = map(i, 0, strip.numPixels() - 1, 0, 255);
brightness = brightness * lightLevel / 1023;
strip.setPixelColor(i, strip.Color(brightness, 0, 0));
}
strip.show();
delay(100);
}
```
## Time is Coming
Name:Rongtian Xie
Beschreibung:
Wenn die Weckzeit erreicht ist, treibt das Signal den Servomotor an, der die Teile vorwärts und rückwärts bewegt.
Der Servomotor ist mit dem RTC-Modul und dem LCD-Modul verbunden und bildet zusammen mit zwei Schaltertasten eine grundlegende Weckerstruktur. Die Schalter steuern und setzen die auf dem LCD-Modul angezeigte Zeit und die Weckzeit ein. Wenn die Weckzeit erreicht ist, dreht der Servomotor um einen voreingestellten Winkel und bewegt das LCD-Modul auf der mechanischen Struktur vorwärts und rückwärts.
video:https://drive.google.com/file/d/1A8P9X2iR6KzHH8C1FlC9VHreEKSp0koD/view?usp=drive_link
photo:
https://drive.google.com/file/d/1AKEa6-jrd_2b1M7l3hu_w1j9HzEch1Xr/view?usp=drive_link
# include <RTClib.h>
#include <Servo.h>
# include <LiquidCrystal_I2C.h>
// Name des RTC-Moduls
RTC_DS3231 rtc;
LiquidCrystal_I2C lcd(0x27, 20, 4);
Servo servo1;
int Lautsprecher = 2;
int TasterLinks = 7;
int i;
int TasterRechts = 8;
int TasterLesenLinks;
int TasterLesenRechts;
// Beginn der Weckzeit
int StundeWeckzeit = 6;
int MinuteWeckzeit = 0;
// Dauer des Signal
int DauerWecksignal = 3;
// Zeit messen für Ticken der Uhr
long Startzeit;
long ZeitJetzt;
void setup()
{
pinMode(TasterLinks, INPUT_PULLUP);
pinMode(TasterRechts, INPUT_PULLUP);
Serial.begin(9600);
servo1.attach(9);
// auf serielle Verbindung warten
while (!Serial) {;}
rtc.begin();
/*
wenn Datum und Zeit nicht korrekt -> Datum/Zeit setzen
Jahr, Monat, Tag, Stunde, Minute, Sekunde
keine führende 0 setzen
rtc.adjust(DateTime(2020, 12, 13, 13, 31, 30));
*/
// rtc.adjust(DateTime(2020, 12, 13, 13, 31, 30));
// LCD initialisieren
lcd.init();
lcd.backlight();
Serial.println("Bitte die Weckzeit eingeben:");
Serial.println("Taster links -> Stunde +/Taster rechts -> Minute +");
Startzeit = millis();
}
void loop()
{
String Stunde, Minute, Weckzeit;
// aktuelle Zeit lesen
DateTime aktuell = rtc.now();
// Stunde einstellen
TasterLesenLinks = digitalRead(TasterLinks);
// Minute einstellen
if (TasterLesenLinks == LOW)
{
delay(200);
if (StundeWeckzeit >= 24) StundeWeckzeit = 1;
else StundeWeckzeit ++;
}
TasterLesenRechts = digitalRead(TasterRechts);
if (TasterLesenRechts == LOW)
{
delay(200);
if (MinuteWeckzeit >= 59) MinuteWeckzeit = 0;
else MinuteWeckzeit ++;
}
// Wochentag, Datum und Zeit anzeigen
lcd.setCursor(0, 2);
/*
Wochentag anzeigen
0 = Sonntag
1 = Montag
...
6 = Samstag
*/
lcd.setCursor(0, 0);
// lcd.print(" ");
lcd.print(aktuell.year());
lcd.print("/");
// Monatsnamen anzeigen
switch (aktuell.month())
{
case 1:
lcd.print("01");
break;
case 2:
lcd.print("02");
break;
case 3:
lcd.print("03");
break;
case 4:
lcd.print("04");
break;
case 5:
lcd.print("05");
break;
case 6:
lcd.print("06");
break;
case 7:
lcd.print("07");
break;
case 8:
lcd.print("08");
break;
case 9:
lcd.print("09");
break;
case 10:
lcd.print("10");
break;
case 11:
lcd.print("11");
break;
case 12:
lcd.print("12");
break;
}
lcd.print("/");
lcd.print(aktuell.day());
// switch (aktuell.dayOfTheWeek())
// {
// case 0:
// lcd.print("Sonntag");
// break;
// case 1:
// lcd.print("Montag");
// break;
// case 2:
// lcd.print("Dienstag");
// break;
// case 3:
// lcd.print("Mittwoch");
// break;
// case 4:
// lcd.print("Donnerstag");
// break;
// case 5:
// lcd.print("Freitag");
// break;
// case 6:
// lcd.print("Samstag");
// break;
// }
lcd.setCursor(11, 0);
// wenn Stunden < 10 -> führende 0 setzen
if (aktuell.hour() < 10) lcd.print("0");
lcd.print(aktuell.hour());
lcd.print(':');
// wenn Minuten < 10 -> führende 0 setzen
if (aktuell.minute() < 10) lcd.print("0");
lcd.print(aktuell.minute());
lcd.print(' ');
lcd.print(':');
// wenn Sekunden < 10 -> führende 0 setzen
if (aktuell.second() < 10) lcd.print("0");
lcd.print(aktuell.second());
/*
Weckzeit formatieren -> führende 0 ergänzen
4 mögliche Fälle
Stunde < 10 Minute < 10
Stunde < 10 Minute > 9
Stunde > 10 Minute < 10
Stunde > 10 Minute > 9
*/
if (StundeWeckzeit < 10 && MinuteWeckzeit < 10) Weckzeit = "0" + String(StundeWeckzeit) + ":0" + String(MinuteWeckzeit);
if (StundeWeckzeit < 10 && MinuteWeckzeit > 9) Weckzeit = "0" + String(StundeWeckzeit) + ":" + String(MinuteWeckzeit);
if (StundeWeckzeit > 9 && MinuteWeckzeit < 10) Weckzeit = String(StundeWeckzeit) + ":0" + String(MinuteWeckzeit);
if (StundeWeckzeit > 9 && MinuteWeckzeit > 9) Weckzeit = String(StundeWeckzeit) + ":" + String(MinuteWeckzeit);
lcd.setCursor(0, 1);
lcd.print("Weckzeit : " + Weckzeit);
// führende 0 setzen
if (aktuell.hour() < 10) Stunde = "0" + String(aktuell.hour());
else Stunde = String(aktuell.hour());
// führende 0 setzen
if (aktuell.minute() < 10) Minute = "0" +
String(aktuell.minute());
else Minute = String(aktuell.minute());
// String zusammensetzen
String aktuelleZeit = Stunde + ":" + Minute; //String是字符
if (aktuelleZeit == Weckzeit && aktuell.second() < DauerWecksignal)//转半程180度用时12秒
{
Serial.print("7");
for(i=1; i<=180;i=i+1)//(i=1; i<=180;i=i+1)
{servo1.write(i);
Serial.print(i);
delay(80);
}
for(i=180; i<=180 && i>=0 ;i=i-1)//x为摆动度数i-x,(i=180; i<=180 && i>=0 ;i=i-1)
{servo1.write(i);
Serial.print(i);
delay(80);//摆动一度的延迟
}
}
/*
Ticken der Uhr
aktuelle Zeit (ZeitJetzt) messen
millis() -> Zeit, die seit dem Start des Programms
vergangen ist
wenn die Differenz zwischen der gerade gemessenen Zeit
und der im setup gemessenen Startzeit >= 1000 (1 Sekunde) ist
-> kurzen Ton wiedergeben
Startzeit muss anschließend auf die aktuelle Zeit gesetzt werden
*/
ZeitJetzt = millis();
if (ZeitJetzt - Startzeit >= 1000)
{
servo1.write(0);
Startzeit = ZeitJetzt;
}
}