Arduino Eğitim Kiti – Tüm Yıl İçin Arduino Müfredatı: Ders 35 İleri Düzey Uygulamalar / Mario Oyunu için isterseniz sunu şeklinde alt taraftaki kutucuğu büyüterek takip edebilir, isterseniz de tüm sunu sayfalarının makale haline dönüştürülmüş versiyonu takip edebilirsiniz. İçerikler büyük oranda aynıdır. Sınıf ortamında kolaylık olması açısından sunu şeklinde de sunulmuştur.

Ders İçeriği:

İleri Düzey Uygulamalar

 

Ders Kazanımları:

  • Isı,Nem,Hava Kalitesi Ölçüm Bilgilerini LCD Ekranda Gösterme programını yardım almadan başarılı bir şekilde tasarlar.
  • Mario oyunu ‘nu yardım almadan başarılı bir şekilde tasarlar.

Oluşabilecek Hatalar:

Aşağıdaki programları çalıştırırken birtakım hatalarla karşılaşabilirsiniz. Bu hataların kodların yazımında meydana gelen hatalar dışında başka sebeplerle ortaya çıkması muhtemeldir. Bu hatalardan sık karşılaşılanlara aşağıda değinilmiştir.

Kart Seçilmesinden Kaynaklı Hata:

Arduino kurulumu gerçekleştirildikten sonra araçlar menüsünden doğru kartın seçilmesi gerekmektedir. Kart seçilmediğinde “Karta yüklenirken bir sorun oluştu.” benzeri bir hata alabilirsiniz.

USB Portun Seçilmesiyle İlgili Hatalar:

Arduino kurulumu gerçekleştirildikten sonra araçlar menüsünden doğru portun seçilmesi gerekmektedir. Bu port Arduino Uno’nun bilgisayara bağlandığı usb porttur. Farklı şekilde bilgisayarınızda usb driver yüklenmemiş olabilir. Bu gibi hatalarda “Port bulunamadı.” gibi hatalar almanız muhtemeldir.


Uyarı:

Aşağıdaki programı tasarlayıp çalıştırdığınızda LCD ekranda sadece parlaklık varsa ve bilgi alamıyorsanız bunun sebebi LCD ekranın kontrast ayarının düşük olması olabilir.

Bu ayar LCD ekranın arka kısmında (LCD ekranı yıldız tornavida ile sökmeniz gerekecek)  I2C modülünün üzerindeki potansiyometre ile yapılabilir. Tornavida yardımı ile potansiyometreyi çevirerek kontrast düzeyini ayarlayabilirsiniz.

Ayrıca kodları yazarken I2C modülün adresini kendi modülünüzün adresine göre düzeltmeyi unutmayın!

(I2C modülünüzün adresini bilmiyorsanız 15. derste tarif edildiği şekilde bulabilirsiniz.)


Uygulama 1: Isı,Nem,Hava Kalitesi Ölçüm Bilgilerini LCD Ekranda Gösterme

 

Kullanılacak Malzemeler:

Bağlantı Şeması:

Bağlantılar şekildeki gibi yapılır.

  1. Arduino üzerindeki 5V pini breadboard üzerinde “+” hatta, GND pini ise yine breadboard üzerinde “-” hatta bağlanır.
  2. Gaz Sensörünün VCC pini “+” hatta, GND pini “-” hatta, A0 Arduino Uno üzerinde A0’a, D0 Arduino Uno üzerinde 8 nolu hatta bağlanır.
  3. L9110 fan modülünün VCC pini Arduino Uno’nun Vin pinine, GND pini GND pinine, INA pini 11 nolu pine, INB 12 nolu pine bağlanır.
  4. Isı ve nem sensörünün VCC pini “+” hatta, GND pini “-” hatta, OUT pini 3 nolu dijital pine bağlanır.
  5. LCD ekranın pinleri aşağıdan yukarı doğru sırasıyla “+” hat, “-” hat, A4 analog pini, A5 analog pini şeklinde bağlanır.

Kodlar:

Uygulamanın “.ino” dosyasını (kod dosyasını) buradan indirebilirsiniz.

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>
LiquidCrystal_I2C lcd(0x3F,16,2);
int INB=12;
int INA=11;
#define sensor_pin A0
#define sensor_pin 8
//Sensörün çalışması için gerekli ön ısıtma süresini 5sn olarak belirliyoruz
#define preheat_time 5000
#define DHTPIN 3
#define DHTTYPE DHT11
DHT dht(DHTPIN,DHTTYPE);
void setup() {
pinMode(3,INPUT);
dht.begin();
lcd.begin();
pinMode(11,OUTPUT);
pinMode(12,OUTPUT);
}
void loop()
{
float t=dht.readTemperature();
lcd.setCursor(0,0);
lcd.print("sicaklik :");
lcd.print(t);
if(t>30)
{digitalWrite(INA,LOW);
digitalWrite(INB,HIGH);
delay(1000);}
delay(3000);
for(int i=0;i<=16;i++)
{ lcd.setCursor(i,1);
lcd.print(".");
delay(500);
}
lcd.clear();
float n=dht.readHumidity();
lcd.setCursor(0,0);
lcd.print("Nem: ");
lcd.print(n);
delay(3000);
for(int i=0;i<=16;i++)
{ lcd.setCursor(i,1);
lcd.print(".");
delay(500);
}
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Hava Kontrol");
lcd.setCursor(0,1);
lcd.print("Ediliyor");
delay(5000);
int sensorValue = analogRead(sensor_pin);
if (sensorValue >= 400)
{ lcd.clear();
lcd.setCursor(0,0);
lcd.print("Zararlı gaz");
lcd.setCursor(0,1);
lcd.print("tespit edildi");
delay(4000);
lcd.clear();
}
else
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Hava Temiz");
delay(4000);
lcd.clear();
}
lcd.setCursor(0,0);
lcd.print("Degerler Yeniden");
lcd.setCursor(0,1);
lcd.print("Hesaplaniyor");
delay(3000);
lcd.clear();
}

  • Yukarıdaki bağlantı yapıldığında ve kodlar Arduino Uno’ya yüklendiğinde çalışma tamamlanmış olacaktır.
  • Bu uygulamada ölçülen sıcaklık ve nem, ortamdaki havanın kalitesi LCD ekranda görülecektir.
  • Ayrıca sıcaklık 30 dereceden büyükse Fan Modülü çalışacaktır.

Uygulama 2: Mario Oyunu

 

Kullanılacak Malzemeler:

Bağlantı Şeması:

Bağlantılar şekildeki gibi yapılır.

  1. Arduino üzerindeki 5V pini breadboard üzerinde “+” hatta, GND pini ise breadboard üzerinde “-” hatta bağlanır.
  2. LCD ekranın pinleri aşağıdan yukarı doğru sırasıyla “+” hat, “-” hat, A4 analog pini, A5 analog pini şeklinde bağlanır.
  3. Buzzer breadboard üzerine yerleştirilir. Kısa bacağı “-” hatta, uzun bacağı 3 nolu dijital pine bağlanır.
  4. Buton şekildeki gibi breadboard üzerine yerleştirilir.
  5. Direnç şekildeki gibi butona bağlanır.
  6. Direncin boşta kalan bacağı erkek-erkek jumper kablo ile “-” hatta, direncin diğer bacağı 2 nolu dijital pine bağlanır.
  7. Butonun boşta kalan bacağı ise “+” hatta bağlanır.

Kodlar:

Uygulamanın “.ino” dosyasını (kod dosyasını) buradan indirebilirsiniz.

// ŞEMA
// GND and Pin 3 – Buzzer
// GND and Pin 2 – button
// ——–DISPLAY———
// SCL – A5
// SDA – A4
// GND – GND
// VCC – 5V
#include <LiquidCrystal_I2C.h>
volatile int grasw;
volatile int napis;
volatile int podmenu;
#define PIN_BUTTON 2
#define PIN_AUTOPLAY 1
#define PIN_READWRITE 10
#define PIN_CONTRAST 12
#define SPRITE_RUN1 1
#define SPRITE_RUN2 2
#define SPRITE_JUMP 3
#define SPRITE_JUMP_UPPER '.'
#define SPRITE_JUMP_LOWER 4
#define SPRITE_TERRAIN_EMPTY ' '
#define SPRITE_TERRAIN_SOLID 5
#define SPRITE_TERRAIN_SOLID_RIGHT 6
#define SPRITE_TERRAIN_SOLID_LEFT 7
#define HERO_HORIZONTAL_POSITION 1
#define TERRAIN_WIDTH 16
#define TERRAIN_EMPTY 0
#define TERRAIN_LOWER_BLOCK 1
#define TERRAIN_UPPER_BLOCK 2
#define HERO_POSITION_OFF 0
#define HERO_POSITION_RUN_LOWER_1 1
#define HERO_POSITION_RUN_LOWER_2 2
#define HERO_POSITION_JUMP_1 3
#define HERO_POSITION_JUMP_2 4
#define HERO_POSITION_JUMP_3 5
#define HERO_POSITION_JUMP_4 6
#define HERO_POSITION_JUMP_5 7
#define HERO_POSITION_JUMP_6 8
#define HERO_POSITION_JUMP_7 9
#define HERO_POSITION_JUMP_8 10
#define HERO_POSITION_RUN_UPPER_1 11
#define HERO_POSITION_RUN_UPPER_2 12
LiquidCrystal_I2C lcd(0x27,16,2);
static char terrainUpper[TERRAIN_WIDTH + 1];
static char terrainLower[TERRAIN_WIDTH + 1];
static bool butonabasildi = false;
char secim;
char secimpoz;
void grafikbaslat(){
static byte graphics[] = {
// Çalışma Pozisyonu 1
B01100,
B01100,
B00000,
B01110,
B11100,
B01100,
B11010,
B10011,
// Çalışma Pozisyonu 2
B01100,
B01100,
B00000,
B01100,
B01100,
B01100,
B01100,
B01110,
// Zıplama
B01100,
B01100,
B00000,
B11110,
B01101,
B11111,
B10000,
B00000,
// Aşağı düşüş
B11110,
B01101,
B11111,
B10000,
B00000,
B00000,
B00000,
B00000,
// Zemin
B11111,
B11111,
B11111,
B11111,
B11111,
B11111,
B11111,
B11111,
// Sağ Zemin
B00011,
B00011,
B00011,
B00011,
B00011,
B00011,
B00011,
B00011,
// Sol Zemin
B11000,
B11000,
B11000,
B11000,
B11000,
B11000,
B11000,
B11000,
};
int i;
for (i = 0; i < 7; ++i) {
lcd.createChar(i + 1, &graphics[i * 8]);
}
for (i = 0; i < TERRAIN_WIDTH; ++i) {
terrainUpper[i] = SPRITE_TERRAIN_EMPTY;
terrainLower[i] = SPRITE_TERRAIN_EMPTY;
}
}
void advanceTerrain(char* terrain, byte newTerrain){
for (int i = 0; i < TERRAIN_WIDTH; ++i) {
char current = terrain[i];
char next = (i == TERRAIN_WIDTH-1) ? newTerrain : terrain[i+1];
switch (current){
case SPRITE_TERRAIN_EMPTY:
terrain[i] = (next == SPRITE_TERRAIN_SOLID) ?
SPRITE_TERRAIN_SOLID_RIGHT : SPRITE_TERRAIN_EMPTY;
break;
case SPRITE_TERRAIN_SOLID:
terrain[i] = (next == SPRITE_TERRAIN_EMPTY) ? SPRITE_TERRAIN_SOLID_LEFT :
SPRITE_TERRAIN_SOLID;
break;
case SPRITE_TERRAIN_SOLID_RIGHT:
terrain[i] = SPRITE_TERRAIN_SOLID;
break;
case SPRITE_TERRAIN_SOLID_LEFT:
terrain[i] = SPRITE_TERRAIN_EMPTY;
break;
}
}
}
void gl (int czas, int glos){
tone(3, glos);
delay(czas);
noTone(3);
}
bool drawHero(byte position, char* terrainUpper, char* terrainLower, unsigned int score) {
bool carpismak = false;
char upperSave = terrainUpper[HERO_HORIZONTAL_POSITION];
char lowerSave = terrainLower[HERO_HORIZONTAL_POSITION];
byte upper, lower;
switch (position) {
case HERO_POSITION_OFF:
upper = lower = SPRITE_TERRAIN_EMPTY;
break;
case HERO_POSITION_RUN_LOWER_1:
upper = SPRITE_TERRAIN_EMPTY;
lower = SPRITE_RUN1;
break;
case HERO_POSITION_RUN_LOWER_2:
upper = SPRITE_TERRAIN_EMPTY;
lower = SPRITE_RUN2;
break;
case HERO_POSITION_JUMP_1:
case HERO_POSITION_JUMP_8:
upper = SPRITE_TERRAIN_EMPTY;
lower = SPRITE_JUMP;
break;
case HERO_POSITION_JUMP_2:
case HERO_POSITION_JUMP_7:
upper = SPRITE_JUMP_UPPER;
lower = SPRITE_JUMP_LOWER;
break;
case HERO_POSITION_JUMP_3:
case HERO_POSITION_JUMP_4:
case HERO_POSITION_JUMP_5:
case HERO_POSITION_JUMP_6:
upper = SPRITE_JUMP;
lower = SPRITE_TERRAIN_EMPTY;
break;
case HERO_POSITION_RUN_UPPER_1:
upper = SPRITE_RUN1;
lower = SPRITE_TERRAIN_EMPTY;
break;
case HERO_POSITION_RUN_UPPER_2:
upper = SPRITE_RUN2;
lower = SPRITE_TERRAIN_EMPTY;
break;
}
if (upper != ' ') {
terrainUpper[HERO_HORIZONTAL_POSITION] = upper;
carpismak = (upperSave == SPRITE_TERRAIN_EMPTY) ? false : true;
}
if (lower != ' ') {
terrainLower[HERO_HORIZONTAL_POSITION] = lower;
carpismak |= (lowerSave == SPRITE_TERRAIN_EMPTY) ? false : true;
}
byte digits = (score > 9999) ? 5 : (score > 999) ? 4 : (score > 99) ? 3 : (score > 9) ? 2 : 1;
// Sahneyi çiz
terrainUpper[TERRAIN_WIDTH] = '\0';
terrainLower[TERRAIN_WIDTH] = '\0';
char temp = terrainUpper[16-digits];
terrainUpper[16-digits] = '\0';
lcd.setCursor(0,0);
lcd.print(terrainUpper);
terrainUpper[16-digits] = temp;
lcd.setCursor(0,1);
lcd.print(terrainLower);
lcd.setCursor(16 – digits,0);
lcd.print(score);
terrainUpper[HERO_HORIZONTAL_POSITION] = upperSave;
terrainLower[HERO_HORIZONTAL_POSITION] = lowerSave;
return carpismak;
}
// Düğmeyi bir kesinti olarak ele almak
void buttonPush() {
butonabasildi = true;
}
void gra(int poziomgry){
static byte heroPos = HERO_POSITION_RUN_LOWER_1;
static byte newTerrainType = TERRAIN_EMPTY;
static byte newTerrainDuration = 1;
static bool playing = false;
static bool blink = false;
static unsigned int distance = 0;
if (!playing) {
drawHero((blink) ? HERO_POSITION_OFF : heroPos, terrainUpper, terrainLower, distance >> 3);
if (blink) {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Bas Zipla");
}
delay(250);
blink = !blink;
if (butonabasildi) {
gl(100,400);
gl(100,600);
gl(100,400);
grafikbaslat();
heroPos = HERO_POSITION_RUN_LOWER_1;
playing = true;
butonabasildi = false;
distance = 0;
}
return;
}
// Araziyi sola kaydır
advanceTerrain(terrainLower, newTerrainType == TERRAIN_LOWER_BLOCK ? SPRITE_TERRAIN_SOLID :
SPRITE_TERRAIN_EMPTY);
advanceTerrain(terrainUpper, newTerrainType == TERRAIN_UPPER_BLOCK ? SPRITE_TERRAIN_SOLID :
SPRITE_TERRAIN_EMPTY);
// Sağa girmek için yeni arazi yap
if (–newTerrainDuration == 0) {
if (newTerrainType == TERRAIN_EMPTY) {
newTerrainType = (random(3) == 0) ? TERRAIN_UPPER_BLOCK : TERRAIN_LOWER_BLOCK;
newTerrainDuration = 2 + random(10);
} else {
newTerrainType = TERRAIN_EMPTY;
newTerrainDuration = 10 + random(10);
}
}
if (butonabasildi) {
if (heroPos <= HERO_POSITION_RUN_LOWER_2)
gl(100,300);
heroPos = HERO_POSITION_JUMP_1;
butonabasildi = false;
}
if (drawHero(heroPos, terrainUpper, terrainLower, distance >> 3)) {
playing = false; // Kahraman bir şeye çaptı.
gl(100,500);
gl(100,400);
gl(120,300);
gl(160,400);
lcd.clear();
}
else {
if (heroPos == HERO_POSITION_RUN_LOWER_2 || heroPos == HERO_POSITION_JUMP_8) {
heroPos = HERO_POSITION_RUN_LOWER_1;
} else if ((heroPos >= HERO_POSITION_JUMP_3 && heroPos <= HERO_POSITION_JUMP_5)
&& terrainLower[HERO_HORIZONTAL_POSITION] != SPRITE_TERRAIN_EMPTY) {
heroPos = HERO_POSITION_RUN_UPPER_1;
} else if (heroPos >= HERO_POSITION_RUN_UPPER_1 && terrainLower[HERO_HORIZONTAL_POSITION]
== SPRITE_TERRAIN_EMPTY) {
heroPos = HERO_POSITION_JUMP_5;
} else if (heroPos == HERO_POSITION_RUN_UPPER_2) {
heroPos = HERO_POSITION_RUN_UPPER_1;
} else {
++heroPos;
}
++distance;
digitalWrite(PIN_AUTOPLAY, terrainLower[HERO_HORIZONTAL_POSITION + 2]
== SPRITE_TERRAIN_EMPTY ? HIGH : LOW);
}
delay(poziomgry);
}
void setup(){
pinMode(4, INPUT_PULLUP);
pinMode(3, OUTPUT);
pinMode(PIN_BUTTON, INPUT);
digitalWrite(PIN_BUTTON, HIGH);
napis = 1;
attachInterrupt(0/*PIN_BUTTON*/, buttonPush, FALLING);
grafikbaslat();
lcd.begin();
do{menu();}while(digitalRead(2) == HIGH);
}
void loop() {
switch (grasw) {
case 1:
gra(70);
break;
case 2:
gra(50);
break;
case 3:
gra(15);
break;
case 4:
gra(1);
break;
}
}
void menu() {
if (napis > 4 || napis < 0) {napis == 0;}
if (digitalRead(4) == LOW) { napis++;}
switch (napis) {
case 1:
if(digitalRead(2) == LOW) {
grasw = 1;
grasw;}
break;
case 2:
if(digitalRead(2) == LOW) {
grasw = 2;
grasw;}
break;
case 3:
if(digitalRead(2) == LOW) {
grasw = 3;
grasw;}
break;
case 4:
if(digitalRead(2) == LOW) {
grasw = 4;
grasw;}
break;
default:
napis = 0;
break;
}
}

  • Yukarıdaki bağlantı yapıldığında ve kodlar Arduino Uno’ya yüklendiğinde çalışma tamamlanmış olacaktır.
  • Bu uygulama karta yüklendiğinde LCD ekranda “Bas Zipla” şeklinde bir uyarı çıkacak.
  • Butona basıldığında karakter yürümeye başlayacaktır.
  • Karakter engele yaklaştığında butona tekrar basılarak karakterin engelin üzerinden zıplaması sağlanabilir.
  • Amaç burada engellere çarpmamaktır.
  • Çarptığı taktirde kaç saniye oyunda kaldığınız sağ üst kısımda yazacaktır.

CEVAP VER

Lütfen yorumunuzu giriniz!
Lütfen isminizi buraya giriniz