Kubus LED + ular

Kata Pengantar


Dalam artikel ini, kami (karena artikel itu ditulis dan dibuat oleh proyek yang terdiri dari 2 orang) akan memberi tahu Anda bagaimana kami menghembuskan kehidupan ke dalam game lama, dilupakan oleh semua orang.

gambar

Persiapan


Mari kita mulai dengan kubus. Kami tidak datang dengan "sepeda" dan memutuskan untuk mencari solusi yang sudah jadi. Artikel ini didasarkan pada artikel oleh penulis Norwegia, meskipun beberapa perubahan telah dibuat, yang menurut saya bermanfaat.

Buat kubus LED Anda sendiri


Setelah membahas beberapa poin, diputuskan untuk membuat kubus 8x8x8. Kami berhasil membeli 1000 LED dalam jumlah besar dengan harga yang baik, hanya apa yang Anda butuhkan, meskipun ini bukan LED yang benar-benar cocok. Secara visual, LED biru dengan lensa matte akan terlihat lebih baik, kilauannya tidak begitu cerah dan lebih seragam. Ada masalah lain dengan LED transparan, lapisan bawah menyoroti yang atas. Namun, terlepas dari semua ini, LED harus cukup cerah untuk membuat gambar lebih jernih. Untuk transparansi yang lebih besar dari kubus, lebih baik untuk mengambil LED kecil, misalnya, 3 mm. Poin lain ketika memilih LED adalah panjang kaki. Kami akan membuat bingkai kubus dari kaki LED, jadi mereka tidak boleh lebih kecil dari ukuran kandang.

Poin penting lainnya ketika membangun sebuah kubus adalah ukurannya. Kami membuat bingkai menggunakan kaki LED, meskipun ada cara di mana batang logam atau kawat digunakan. Panjang katoda LED kami ternyata sekitar 25 mm, jadi kami memilih ukuran sel 20 mm, dan memutuskan untuk menggunakan sisanya untuk menyolder, sehingga kubus akan lebih kuat. Ini hanya sedikit perbedaan dari desain penulis artikel di atas.

Langkah selanjutnya adalah membuat tata letak untuk menyolder lapisan kubus, ini akan membantu memfasilitasi penyolderan dan kubus akan lebih merata. Tata letaknya sangat sederhana, saya mengambil sepotong kayu lapis, menggambarnya seukuran kubus saya dan mengebor lubang di persimpangan garis seukuran LED.

gambar

Solder beberapa lapisan, saya menyadari bahwa desain ini tidak cukup kaki, yang berfungsi sebagai baut panjang.

Sebelum Anda mulai menyolder kubus, saya menyarankan Anda untuk mempersiapkan semuanya. Dari pengalaman pribadi saya dapat mengatakan bahwa jauh lebih nyaman untuk melakukan ini bersama, karena benar-benar tidak ada cukup tangan, satu orang menggunakan katoda, dan yang kedua memberi solder dan solder. Anda perlu melakukan ini dengan cepat, LED kecil dan takut terlalu panas. Juga dalam manual berbeda mereka mengatakan periksa setiap LED sebelum menyolder. Saya tidak mengerti intinya, menghabiskan banyak waktu untuk operasi yang pada dasarnya tidak berarti. Kami membeli LED baru dan semuanya ternyata berfungsi. Tetapi ketika Anda menyolder lapisan, itu sudah layak untuk memeriksa semuanya dengan baik, karena menyolder LED dari pusat adalah tugas yang tidak menyenangkan, itu diperiksa oleh pengalaman pribadi.

Jadi, mari kita lanjutkan langsung ke solder. Saya tidak bisa mengatakan bahwa ini adalah cara yang paling pasti, tetapi kami melakukannya dengan cara itu. Untuk mulai dengan, kami memiliki semua LED di tata letak kami, disarankan untuk menginstalnya dengan lancar, maka tidak akan ada cara untuk memperbaiki sesuatu.

gambar

gambar

Lalu kami menekuk katoda sehingga saling tumpang tindih. Ketika semuanya sudah siap, Anda dapat mulai menyolder, tetapi Anda harus ingat tentang kemungkinan panas berlebih, dan jika penyolderan gagal, jangan buru-buru menyolder, lebih baik membiarkan LED dingin.

Menyolder semua LED, kami mendapatkan 8 strip 8 LED. Untuk mengubah semuanya menjadi satu lapisan, kami menggunakan kawat aluminium biasa, yang sebelumnya diluruskan. Kami memutuskan untuk menggunakan hanya 2 "batang" ini, agar tidak menyulitkan desain, dengan cara ternyata cukup kuat.

Menyolder lapisan terakhir tidak perlu mendapatkannya karena Anda harus memasukkannya kembali. Sekarang kita memiliki 8 layer, kita harus menggabungkannya menjadi satu kubus. Untuk membuat kubus lebih atau kurang genap, saya harus membengkokkan anoda seperti yang ditunjukkan pada gambar, sekarang berputar di sekitar LED, dan dapat disolder dengan rapi.

gambar

gambar

Kami menyolder kubus dari lapisan atas ke paling bawah, sambil terus-menerus memeriksa pengoperasian LED, lebih baik jangan malas, karena dengan begitu akan lebih sulit untuk memperbaiki kesalahan. Lebih baik untuk mengatur ketinggian antara lapisan dengan bantuan beberapa templat, penulis artikel di atas menggunakan mahkota biasa. Kami tidak memiliki apa pun yang cocok, tetapi ada dua dari kami, jadi kami memutuskan untuk mengatur semuanya secara manual. Ternyata cukup lancar, tetapi tidak sempurna.

Setelah melakukan semua tindakan ini, Anda akan mendapatkan kubus LED yang Anda kumpulkan dan beberapa jari terbakar, tetapi ini sudah tergantung pada keakuratan Anda.

gambar

gambar

Desain sirkuit


Untuk mengimplementasikan ide-ide kami, kami membutuhkan semacam mikrokontroler. Kami memutuskan untuk tetap menggunakan mikrokontroler Arduino Leonardo. Kami tidak ingin repot dengan programmer dan perangkat lunak yang diperlukan, hanya saja kami tidak membutuhkan prosesor yang kuat untuk tugas-tugas kami. Setelah perangkat selesai, kami menyadari bahwa itu mungkin untuk menggunakan Nano, tetapi ini tidak begitu penting. Untuk mengontrol kubus, kami memutuskan untuk menggunakan telepon yang terhubung ke Arduino melalui Bluetooth, dalam kasus kami HC-05 digunakan, tetapi Anda dapat menggunakan yang lain.

gambar

Tetapi yang benar-benar penting adalah jumlah pin mikrokontroler, karena kami mendapat 64 pin anoda dan 8 pin katoda, tetapi kami akan berbicara tentang menghubungkannya nanti. Kami memutuskan untuk memperluas port IO dengan bantuan register geser, dalam kasus kami ini adalah register TI 74HC595 dalam paket DIP untuk menyolder soket ke papan, dan memasukkan chip itu sendiri ke dalamnya. Anda dapat membaca lebih lanjut tentang register ini dalam lembar data, saya hanya akan mengatakan bahwa kami menggunakan segalanya kecuali sinyal setel ulang register, kami menerapkan sebuah unit padanya, karena itu terbalik, dan kami membalikkan output memungkinkan input ke ground, itu juga terbalik dan kami selalu ingin menerima data dari register. Anda juga dapat menggunakan register berurutan, tetapi kemudian Anda harus meletakkan decoder untuk memilih register mana yang akan dituliskan informasinya.

gambar

Untuk menutup sirkuit ke ground, memilih level yang ingin kita nyalakan, kita perlu saklar transistor, baik, atau hanya transistor. Kami menggunakan transistor bipolar daya rendah jenis NPN biasa yang terhubung secara paralel dalam 2. Tidak yakin apakah ini masuk akal, tapi sepertinya arus mengalir lebih baik. Basis melalui resistor pull-up 100 Ohm terhubung ke mikrokontroler, yang akan membuka transistor kami. Lapisan kubus terhubung ke kolektor, dan emitor terhubung ke tanah.

gambar

gambar

Menyatukan kubus


Mereka tidak dapat menemukan sesuatu yang lebih baik untuk memasok kubus daripada catu daya dari tablet, yang parameternya 5 V dan 2 A. Mungkin ini tidak cukup, tetapi kubus bersinar cukup cerah. Agar tidak membakar LED, semua terminal anoda terhubung ke register melalui resistor pembatas arus. Menurut perhitungan saya, mereka seharusnya sekitar 40 Ohm, tetapi saya tidak memilikinya, jadi saya menggunakan 100 Ohm.

Kami menempatkan semua ini di 2 papan sirkuit kecil. Mereka tidak sengaja meracuni apa pun karena kurangnya latihan, mereka hanya menghubungkan semuanya dengan konduktor biasa. Register dengan anoda kubus terhubung menggunakan kabel yang kami ambil dari komputer lama. Lebih mudah menavigasi kabel.

gambar

Mereka memutuskan untuk merakit prototipe pada tata letak yang digunakan untuk penyolderan.

gambar

Setelah merapikan segalanya dan memperbaiki kesalahan yang dilakukan, kami membuat bodi dari laminasi kami, hasilnya bagus karena tidak harus dicat. Inilah hasil akhirnya:

gambar

Jadilah terang!


Ada sebuah kubus, tetap membuatnya bersinar. Selanjutnya, berbagai mode (mode) kubus akan dijelaskan, untuk beralih mana bluetooth + Android digunakan. Aplikasi telepon ditulis menggunakan Cordova. Kode aplikasi tidak akan dijelaskan di sini, tetapi tautan ke repositori disajikan dalam kesimpulan.

Algoritma kubus


Karena kami tidak memiliki akses ke semua LED sekaligus, kami tidak dapat menyalakan semuanya sekaligus. Sebaliknya, kita perlu menyalakannya berlapis-lapis.

Algoritma adalah sebagai berikut:

  1. Lapisan saat ini adalah 0.
  2. Daftarkan masker untuk lapisan saat ini
  3. Tutup transistor untuk lapisan sebelumnya. Jika lapisan saat ini adalah nol, maka lapisan sebelumnya adalah lapisan ke-7
  4. Kami mengklik nilai ke dalam register. Nilai muncul pada output register
  5. Buka transistor untuk lapisan saat ini. Hore, satu lapisan bersinar!
  6. Lapisan saat ini ++. goto: 2

Secara total, algoritma ini berulang cukup cepat, yang memberi kita ilusi bahwa semua LED menyala secara bersamaan (tetapi kita tahu bahwa ini tidak demikian). Masker disimpan dalam array 64x8 byte.

Menulis mod

Mode-mode ini tidak muncul dalam urutan yang disajikan di sini, jadi tolong jangan menghukum mereka dengan memberi nomor pada kode. Mari kita mulai dengan yang paling sederhana: nyalakan semua LED.

Nyalakan kubus
void Mode_2_Init() {
	for (byte z = 0; z < CUBE_EDGE_SIZE; z++) {
		for (byte y = 0; y < CUBE_EDGE_SIZE; y++) {
			for (byte x = 0; x < CUBE_EDGE_SIZE; x++) {
				cube->data[z * CUBE_LEVEL_SIZE + y * CUBE_EDGE_SIZE + x] = 1;
			}
		}
	}
}


Mod "lengket"

Ide: hanya dua lapisan burn nol dan ketujuh, dan keduanya berbanding terbalik satu sama lain (LED pada posisi X menyala hanya pada salah satu layer). Posisi dipilih secara acak (untuk beberapa alasan semua orang berusaha menemukan algoritma untuk memilih posisi), dan LED pada posisi ini "merangkak" ke lapisan atas jika dinyalakan pada lapisan bawah, dan sesuai dengan yang lebih rendah jika menyala di atas.

Kode lengket
void Mode_0() {
	byte positionToMove = random(CUBE_LEVEL_SIZE);
	byte fromLevel = cube->data[positionToMove] == 1 ? 0 : 7;
	bool top = fromLevel == 0;
	cube->ShowDataXTimes(5);
	while (true) {
		byte toLevel = top ? fromLevel + 1 : fromLevel - 1;
		if (toLevel >= CUBE_EDGE_SIZE || toLevel < 0) break;
		cube->data[fromLevel * CUBE_LEVEL_SIZE + positionToMove] = 0;
		cube->data[toLevel * CUBE_LEVEL_SIZE + positionToMove] = 1;
		cube->ShowDataXTimes(2);
		fromLevel = toLevel;
	}
}

void Mode_0_Init() {
	cube->Clear();
	for (byte i = 0; i < CUBE_LEVEL_SIZE; i++) {
		byte value = random(0, 2);  // max - 1
		cube->data[i] = value;  //first level
		cube->data[i + (CUBE_EDGE_SIZE - 1) * CUBE_LEVEL_SIZE] = !value;  //last level
	}
}


Seperti apa kehidupan ini:



“Mod lain yang lengket”

Mod ini mirip dengan yang sebelumnya, kecuali bahwa lapisannya tidak terbakar, tetapi wajah, dan lampu dari wajah ini, satu per satu bergerak ke sebaliknya, dan kemudian kembali.

Kode lengket lainnya
void Mode_3_Init() {
	cube->Clear();
	positions->clear();
	new_positions->clear();
	mode_3_direction = NORMAL;
	for (short y = 0; y < CUBE_LEVEL_SIZE * CUBE_EDGE_SIZE; y += CUBE_LEVEL_SIZE) {
		for (byte x = 0; x < CUBE_EDGE_SIZE; x++) {
			cube->data[x + y] = 1;
			positions->push_back(x + y);
		}		
	}
}

void Mode_3() {
	if (positions->size() == 0) {
		delete positions;
		positions = new_positions;
		new_positions = new SimpleList<short>();
		mode_3_direction = mode_3_direction == NORMAL ? INVERSE : NORMAL;
	}
	byte item = random(0, positions->size());
	short position = *((*positions)[item]);
	positions->erase(positions->begin() + item);
	byte i = 1;
	while(i++ < CUBE_EDGE_SIZE ) {
		cube->data[position] = 0;
		if(mode_3_direction == NORMAL) position += CUBE_EDGE_SIZE;
		else position -= CUBE_EDGE_SIZE;
		cube->data[position] = 1;
		cube->ShowDataXTimes(1);
	}
	new_positions->push_back(position);
}




Kubus di dalam kubus

Ide: nyalakan LED di dalam kubus dalam bentuk wajah kubus dengan ukuran dari 1 hingga 8 LED dan sebaliknya.

Kubus di dalam kubus
void Mode_1() {
	cube->Clear();
	for (byte cube_size = 0; cube_size < CUBE_EDGE_SIZE; cube_size++) {
		for (byte level = 0; level <= cube_size; level++) {
			for (byte x = 0; x <= cube_size; x++) {
				for (byte y = 0; y <= cube_size; y ++) {
					cube->data[level * CUBE_LEVEL_SIZE + y * CUBE_EDGE_SIZE + x] =
						(y % cube_size == 0 || x % cube_size == 0)
						&& level % cube_size == 0 ||
						(y % cube_size == 0) && (x % cube_size == 0) ? 1 : 0;
				}
			}
		}
		cube->ShowDataXTimes(5);
	}
	for (byte cube_size = CUBE_EDGE_SIZE - 1; cube_size > 0; cube_size--) {
		for (byte level = 0; level <= cube_size; level++) {
			for (byte x = 0; x <= cube_size; x++) {
				for (byte y = 0; y <= cube_size; y++) {
					cube->data[level * CUBE_LEVEL_SIZE + (CUBE_EDGE_SIZE - 1 - y) * CUBE_EDGE_SIZE + (CUBE_EDGE_SIZE - 1 - x)] =
						(((y % (cube_size - 1) == 0 || x % (cube_size - 1) == 0) && (level % (cube_size - 1) == 0))
						|| ((y % (cube_size - 1) == 0) && (x % (cube_size - 1) == 0) && level % cube_size != 0))
						&& x < (cube_size) && y < (cube_size) ? 1 : 0;
				}
			}
		}
		cube->ShowDataXTimes(5);
	}
}


Seperti apa tampilannya:



Dan akhirnya ular itu

Dari fitur implementasi ular, perlu dicatat bahwa tidak ada batasan di lapangan, dan dengan demikian meninggalkan kubus di satu sisi, Anda muncul di sisi lain. Anda hanya bisa kalah jika menabrak diri sendiri (sebenarnya, Anda tidak bisa menang).
Ada baiknya secara terpisah menceritakan tentang manajemen:

Dalam kasus implementasi dua dimensi dari game ini, tidak ada masalah dengan manajemen: empat tombol dan semuanya jelas. Dalam kasus implementasi tiga dimensi, beberapa opsi kontrol muncul:

1,6 tombol. Dengan opsi ini, tombol memiliki arah gerakannya sendiri: untuk tombol naik dan turun, semuanya jelas, dan tombol yang tersisa dapat "diikat" ke titik mata angin, ketika Anda menekan tombol "kiri", vektor gerakan selalu berubah "barat", dll. Dengan opsi ini, situasi muncul ketika ular bergerak "timur" dan kami mengklik "barat". Karena ular tidak dapat berputar 180 derajat, Anda harus menangani kasing seperti itu secara terpisah.

Tombol 2.4 (Atas Bawah Kiri Kanan). Tindakan tombol-tombol ini mirip dengan yang ada dalam implementasi dua dimensi, kecuali bahwa semua perubahan diambil relatif terhadap arah saat ini dari vektor gerakan. Mari saya jelaskan dengan contoh: ketika bergerak di bidang horizontal, dengan menekan tombol "Atas", kita pergi ke bidang vertikal. Ketika bergerak di bidang vertikal dengan menekan "Atas", kita beralih ke bergerak di bidang horizontal melawan arah sumbu X, untuk "Turun" - ke arah sumbu X, dll.

Tentu saja, kedua opsi memiliki hak untuk ada (akan menarik untuk mengetahui opsi kontrol lainnya). Untuk proyek kami, kami memilih yang kedua.

Kode Arah
void Snake::ApplyUp() {
	switch (direction) {
	case X:
	case Y:
		direction = Z;
		directionType = NORMAL;
		break;
	case Z:
		direction = X;
		directionType = INVERSE;
	}
}

void Snake::ApplyDown() {
	switch (direction) {
	case X:
	case Y:
		direction = Z;
		directionType = INVERSE;
		break;
	case Z:
		direction = X;
		directionType = NORMAL;
	}
}

void Snake::ApplyLeft() {
	switch (direction) {
	case X:
		direction = Y;
		directionType = directionType == NORMAL ? INVERSE : NORMAL;
		break;
	case Y:
		direction = X;
		directionType = directionType;
		break;
	
	case Z:
		direction = Y;
		directionType = NORMAL;
	}
}

void Snake::ApplyRight() {
	switch (direction) {
	case X:
		direction = Y;
		directionType = directionType;
		break;
	case Y:
		direction = X;
		directionType = directionType == NORMAL ? INVERSE : NORMAL;
		break;
	case Z:
		direction = Y;
		directionType = INVERSE;
	}
}

void Snake::ChangeDirection(KEY key) {
	switch(key) {
	case UP:
		ApplyUp();
		break;
	case LEFT:
		ApplyLeft();
		break;
	case RIGHT:
		ApplyRight();
		break;
	case DOWN:
		ApplyDown();
		break;
	}
}


Hasil dari program:





Tautan ke kode sumber firmware kubus dan aplikasi untuk telepon: firmware

aplikasi


Hasil


Hasilnya, kami mendapat konsol primitif dan semacam lampu, dengan kemungkinan pencahayaan dinamis. Di masa depan kami berencana untuk mengembangkan papan sirkuit cetak dan meningkatkan firmware. Dimungkinkan juga untuk menambahkan modul tambahan.

Source: https://habr.com/ru/post/id388369/


All Articles