13' LCD 디스플레이어
왼쪽위 - 디스플레이어 보드, 가운데 - 라즈베리파이4, 오른쪽아래 - USB 충전기, DC/DC 아답터
13' LCD 디스플레이어
왼쪽위 - 디스플레이어 보드, 가운데 - 라즈베리파이4, 오른쪽아래 - USB 충전기, DC/DC 아답터
개요 |
스위치를 이용하여 BootSelect 하기위해 기본적인 python을 이용한 print 시험 |
구성 |
소스코드 |
#i /user/bin/python from gpiozero import Button import subprocess if Button(2).is_pressed & Button(4).is_pressed: print('Gpio_2 & Gpio_4') elif (not Button(2).is_pressed) & Button(4).is_pressed: print('Gpio_4') elif (not Button(4).is_pressed) & Button(2).is_pressed: print('Gpio_2') else: print('Not Input') |
결과 |
목적 : 이동식 Mame게임기 및 Kodi 미디어 플레어 만들기
준비 (국내 온라인 사이트에서 구할수가 없어서 AliExpress에서 구매 진행) (약 $1 = \1,200)
1) Raspberry Pi4 - 4Gb $ 65.52 X1
https://ko.aliexpress.com/item/4000054868537.html?spm=a2g0s.9042311.0.0.683d4c4d07fy7P
2) Raspberry Pi4 방열 케이스 $ 15.19 X1
https://ko.aliexpress.com/item/4000061381216.html?spm=a2g0s.9042311.0.0.683d4c4d07fy7P
3) 게임패드 $ 26.38 X2
https://ko.aliexpress.com/item/32840716891.html?spm=a2g0s.9042311.0.0.683d4c4d07fy7P
4) 13'3인치 Display 모듈 $ 49.40 X1
https://ko.aliexpress.com/item/4000112143939.html?spm=a2g0s.9042311.0.0.683d4c4d07fy7P
5) 기타 : 충전기 5V/3A, USB-C Type Cable, micro HDMI Cable 약\20,000원
6) 아크릴 케이스 : 예상비용 : 3만3천7백원 - 기본적인 설계는 완료했으나. Display 모듈 입고 후 확인하고 제작 예정
https://www.acryiae.com/front/mypage/orderList.do
총 금액 $156.49 + 2만 + 3만3천7백 = \241,488원
많이도 들어갔내...
진행상황
Mame 적용완료,
Mame 2000, 2003, 2010 게임 실행 완료
Kodi 한글화 적용완료,
앞으로 진행
전원 인가시 스위치모드에 따라서 RetroPi 부팅, Kodi 부팅, Raspbian 부팅 설정예정 - 완료
스위치 자동 실행시 RetroPi 게임 실행 안되는 문제 있음.
#소스코드 |
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.IO.Ports; namespace Ultrasonic_RADAR { public partial class Form1 : Form { // 시리얼 관련 변수 string dataIN; //시리얼 읽기 double number1; //문자 -> 부동소수점으로 변경 int measure_flag = 0; // 레이더 그리기 Timer t = new Timer(); int width = 400, height = 400, Hand = 200; int u; int cx, cy; int x, y; int tx, ty, lim = 20; Bitmap bmp; // 픽셀 Pen p; // 선 Graphics g; public Form1() { InitializeComponent(); } private void Form1_Load_1(object sender, EventArgs e) { // 시리얼 포트 초기화 string[] ports = SerialPort.GetPortNames(); cBoxCOMPORT.Items.AddRange(ports); // 레이더 그리기 초기화 bmp = new Bitmap(width + 1, height + 1); this.BackColor = Color.Gray; //center cx = width / 2; cy = height / 2; //initial degree of HAND u = 0; //timer //t.Interval = 5; //in millisecond //t.Tick += new EventHandler(this.t_TICK); //t.Start(); } private void t_TICK(object sender, EventArgs e) { //pen p = new Pen(Color.Green, 1f); //graphics g = Graphics.FromImage(bmp); //calculate x, y coordinate of HAND int tu = (u - lim) % 360; if (u >= 0 && u <= 180) { //right half //u in degree is converted into radian. x = cx + (int)(Hand * Math.Sin(Math.PI * u / 180)); y = cy - (int)(Hand * Math.Cos(Math.PI * u / 180)); } else { x = cx - (int)(Hand * -Math.Sin(Math.PI * u / 180)); y = cy - (int)(Hand * Math.Cos(Math.PI * u / 180)); } if (tu >= 0 && u <= 180) { tx = cx + (int)(150 * Math.Sin(Math.PI * tu / 180)); ty = cy - (int)(150 * Math.Cos(Math.PI * tu / 180)); } else { tx = cx - (int)(150 * -Math.Sin(Math.PI * tu / 180)); ty = cy - (int)(150 * Math.Cos(Math.PI * tu / 180)); } // draw circle g.DrawEllipse(p, 0, 0, width, height); //bigger circle // g.DrawEllipse(p, 80, 80, width - 160, height - 160); //smaller circle // draw perpendicular line // g.DrawLine(p, new Point(cx, 0), new Point(cx, height)); // UP-DOWN // g.DrawLine(p, new Point(cy, 0), new Point(cy, width)); //LEFT-RIGHT //draw HAND // g.DrawLine(new Pen(Color.White, 1f), new Point(cx, cy), new Point(tx, ty)); g.DrawLine(p, new Point(cx, cy), new Point(x, y)); if (serialPort1.IsOpen) { g.DrawLine(new Pen(Color.Red, 1f), new Point(x-1, y-1), new Point(x, y)); } // load bitmap in picturebox1 // 해제 p.Dispose(); g.Dispose(); //update if (u == 360) { u = 0; measure_flag = 0; bmp = new Bitmap(width + 1, height + 1); serialPort1.Write("0"); }else pictureBox1.Image = bmp; } private void btnOpen_Click(object sender, EventArgs e) { try { serialPort1.PortName = cBoxCOMPORT.Text; serialPort1.BaudRate = Convert.ToInt32(cBoxBaudRate.Text); serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived); serialPort1.Open(); progressBar1.Value = 100; } catch (Exception err) { MessageBox.Show(err.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void btnCLose_Click_1(object sender, EventArgs e) { if (serialPort1.IsOpen) { serialPort1.Close(); progressBar1.Value = 0; } } private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e) //시리얼 데이터 읽기 { if (measure_flag == 1) { dataIN = serialPort1.ReadExisting(); try { number1 = System.Convert.ToDouble(dataIN); } catch (FormatException) { } catch (OverflowException) { } Hand = (int)number1; //그리기-값 serialPort1.Write("1"); this.Invoke(new EventHandler(ShowData)); this.Invoke(new EventHandler(t_TICK)); u++; } } private void ShowData(object sender, EventArgs e) //Data 출력 { this.label3.Text = dataIN; } private void Measure_Click(object sender, EventArgs e) { measure_flag = 1; serialPort1.Write("1"); } } } |
#define H 1
#define L 0
#define trigpin 11
#define echopin 12
#define delay_time 10
int Motor[4] = {4,5,6,7};
int M_En[2] = {8,9};
int i, deg = 0;
int flag = 0;
float duration, distance;
void setup() {
for (i=0;i<4;i++){
pinMode(Motor[i], OUTPUT);
}
for (i=0;i<2;i++){
pinMode(M_En[i], OUTPUT);
}
pinMode(trigpin, OUTPUT); //Trig
pinMode(echopin, INPUT); //Echo
Serial.begin(115200); //보레이트 설정
}
void M_Enable(){
for (i=0;i<2;i++){
digitalWrite(M_En[i], H);
}
}
void M_Disable(){
for (i=0;i<2;i++){
digitalWrite(M_En[i], L);
}
}
void UltraSonic_command(){
/////////////////////////UltraSonic 동작 및 거리계산
////////////////////////////////////////////////// 대충 검색해서 퍼옴 - 구지... 이해할필요까지.. 없어보임.
digitalWrite(trigpin, H);
delay(10);
digitalWrite(trigpin, L);
duration = pulseIn(echopin, H);
distance = ((float)(340*duration) / 10000) /2 ;
/////////////////////////시리얼로 프린트? TX 구문인지...
//Serial.print("distance : ");
Serial.println(distance);
}
// 한스텝 동작 -> 거리측정 -> Serial Send
void M_move(int a, int b, int c, int d){
M_Enable();
digitalWrite(4, a); // turn the LED on (HIGH is the voltage level)
digitalWrite(5, b); // turn the LED on (HIGH is the voltage level)
digitalWrite(6, c); // turn the LED on (HIGH is the voltage level)
digitalWrite(7, d); // turn the LED on (HIGH is the voltage level)
UltraSonic_command();
M_Disable();
}
// 오른쪽 동작
void r_Stepping(){
M_move(H,L,L,H);
delay(delay_time); // wait for a second
M_move(H,H,L,L);
delay(delay_time); // wait for a second
M_move(L,H,H,L);
delay(delay_time); // wait for a second
M_move(L,L,H,H);
delay(delay_time); // wait for a second
}
// 왼쪽 동작
void l_Stepping(){
M_move(L,L,H,H);
delay(delay_time); // wait for a second
M_move(L,H,H,L);
delay(delay_time); // wait for a second
M_move(H,H,L,L);
delay(delay_time); // wait for a second
M_move(H,L,L,H);
delay(delay_time); // wait for a second
}
// 오른쪽 360도 -> 왼쪽 360도
void loop() {
if(Serial.available()>0){
flag = Serial.read();
}
if(flag){
l_Stepping();
if(deg < 52)
deg = deg + 1;
else {
flag = 0;
deg = 0;
}
}
}
# 참고동영상 |
https://www.youtube.com/watch?v=4yDbBJLhVso |
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
namespace ComPort
{
public partial class Form1 : Form
{
string dataOUT;
string dataIN;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
string[] ports = SerialPort.GetPortNames();
cBoxCOMPORT.Items.AddRange(ports);
}
private void btnOpen_Click(object sender, EventArgs e)
{
try
{
serialPort1.PortName = cBoxCOMPORT.Text;
serialPort1.BaudRate = Convert.ToInt32(cBoxBaudRate.Text);
serialPort1.DataBits = Convert.ToInt32(cBoxDataBits.Text);
serialPort1.StopBits = (StopBits)Enum.Parse(typeof(StopBits), cBoxStopBits.Text);
serialPort1.Parity = (Parity)Enum.Parse(typeof(Parity), cBoxParityBits.Text);
serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
serialPort1.Open();
progressBar1.Value = 100;
}
catch (Exception err)
{
MessageBox.Show(err.Message,"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void btnCLose_Click(object sender, EventArgs e)
{
if(serialPort1.IsOpen)
{
serialPort1.Close();
progressBar1.Value = 0;
}
}
private void btnSendData_Click(object sender, EventArgs e)
{
if (serialPort1.IsOpen)
{
dataOUT = tBoxDataOut.Text;
serialPort1.Write(dataOUT);
}
}
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
dataIN = serialPort1.ReadExisting();
this.Invoke(new EventHandler(ShowData));
}
private void ShowData(object sender, EventArgs e)
{
tBoxDataIn.Text += dataIN;
}
}
}
# 참고동영상 |
https://www.youtube.com/watch?v=wsMMHaSvvRU |
Imports System
Imports System.Threading
Imports System.IO.Ports
Imports System.ComponentModel
Public Class Form1
Dim myPort As Array
Delegate Sub SetTextCallBack(ByVal [text] As String)
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
myPort = IO.Ports.SerialPort.GetPortNames()
Port_ComboBox.Items.AddRange(myPort)
Write_Button.Enabled = False
End Sub
Private Sub init_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles init_Button.Click
SerialPort1.PortName = Port_ComboBox.Text
SerialPort1.BaudRate = Board_ComboBox.Text
SerialPort1.Open()
init_Button.Enabled = False
Write_Button.Enabled = True
Close_Button.Enabled = True
End Sub
Private Sub Write_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Write_Button.Click
SerialPort1.Write(Input_TextBox.Text & vbCr)
End Sub
Private Sub Close_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Close_Button.Click
SerialPort1.Close()
init_Button.Enabled = True
Write_Button.Enabled = False
Close_Button.Enabled = False
End Sub
Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
ReceivedText(SerialPort1.ReadExisting())
End Sub
Private Sub ReceivedText(ByVal text As String)
If Me.Output_TextBox.InvokeRequired Then
Dim x As New SetTextCallBack(AddressOf ReceivedText)
Me.Invoke(x, New Object() {(text)})
Else
Me.Output_TextBox.Text &= text
Me.Label3.Text = text
End If
End Sub
End Class
# 참고 동영상 |
https://www.youtube.com/watch?v=8WhQATRycTU |
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace RADAR1
{
public partial class Form1 : Form
{
Timer t = new Timer();
int width = 300, height = 300, Hand = 150;
int u;
int cx, cy;
int x, y;
int tx, ty, lim = 20;
Bitmap bmp;
Pen p;
Graphics g;
public Form1()
{
InitializeComponent();
}
private void Form1_Load_1(object sender, EventArgs e)
{
//create Bitmap
bmp = new Bitmap(width + 1, height + 1);
//background color
this.BackColor = Color.Black;
//center
cx = width / 2;
cy = height / 2;
//initial degree of HAND
u = 0;
//timer
t.Interval = 5; //in millisecond
t.Tick += new EventHandler(this.t_TICK);
t.Start();
}
private void t_TICK(object sender, EventArgs e)
{
//pen
p = new Pen(Color.Green, 1f);
//graphics
g = Graphics.FromImage(bmp);
//calculate x, y coordinate of HAND
int tu = (u - lim) % 360;
if (u >= 0 && u <= 180)
{
//right half
//u in degree is converted into radian.
x = cx + (int)(Hand * Math.Sin(Math.PI * u / 180));
y = cy - (int)(Hand * Math.Cos(Math.PI * u / 180));
}
else
{
x = cx - (int)(Hand * -Math.Sin(Math.PI * u / 180));
y = cy - (int)(Hand * Math.Cos(Math.PI * u / 180));
}
if (tu >= 0 && u <= 180)
{
tx = cx + (int)(Hand * Math.Sin(Math.PI * tu / 180));
ty = cy - (int)(Hand * Math.Cos(Math.PI * tu / 180));
}
else
{
tx = cx - (int)(Hand * -Math.Sin(Math.PI * tu / 180));
ty = cy - (int)(Hand * Math.Cos(Math.PI * tu / 180));
}
// draw circle
g.DrawEllipse(p, 0, 0, width, height); //bigger circle
g.DrawEllipse(p, 80, 80, width - 160, height - 160); //smaller circle
// draw perpendicular line
g.DrawLine(p, new Point(cx, 0), new Point(cx, height)); // UP-DOWN
g.DrawLine(p, new Point(cy, 0), new Point(cy, width)); //LEFT-RIGHT
//draw HAND
g.DrawLine(new Pen(Color.Black, 1f), new Point(cx, cy), new Point(tx, ty));
g.DrawLine(p, new Point(cx, cy), new Point(x, y));
// load bitmap in picturebox1
pictureBox1.Image = bmp;
// dispose
p.Dispose();
g.Dispose();
//update
u++;
if (u == 360)
u = 0;
}
}
}
#소스코드 |
#define H 1 #define L 0 #define trigpin 11 #define echopin 12 #define delay_time 990 int Motor[4] = {4,5,6,7}; int M_En[2] = {8,9}; int i, deg = 0; int flag = 0; float duration, distance;
void setup() { //pinMode(4, OUTPUT); //A //pinMode(5, OUTPUT); //B //pinMode(6, OUTPUT); //An //pinMode(7, OUTPUT); //Bn //pinMode(8, OUTPUT); //enable1 //pinMode(9, OUTPUT); //enable2
for (i=0;i<4;i++){ pinMode(Motor[i], OUTPUT); } for (i=0;i<2;i++){ pinMode(M_En[i], OUTPUT); }
pinMode(trigpin, OUTPUT); //Trig pinMode(echopin, INPUT); //Echo Serial.begin(9600); //보레이트 설정 } void M_Enable(){ for (i=0;i<2;i++){ digitalWrite(M_En[i], H); } } void M_Disable(){ for (i=0;i<2;i++){ digitalWrite(M_En[i], L); } } void UltraSonic_command(){ /////////////////////////UltraSonic 동작 및 거리계산 ////////////////////////////////////////////////// 대충 검색해서 퍼옴 - 구지... 이해할필요까지.. 없어보임. digitalWrite(trigpin, H); delay(10); digitalWrite(trigpin, L); duration = pulseIn(echopin, H); distance = ((float)(340*duration) / 10000) /2 ; /////////////////////////시리얼로 프린트? TX 구문인지... Serial.print("distance : "); Serial.println(distance); } // 한스텝 동작 -> 거리측정 -> Serial Send void M_move(int a, int b, int c, int d){ M_Enable(); digitalWrite(4, a); // turn the LED on (HIGH is the voltage level) digitalWrite(5, b); // turn the LED on (HIGH is the voltage level) digitalWrite(6, c); // turn the LED on (HIGH is the voltage level) digitalWrite(7, d); // turn the LED on (HIGH is the voltage level) UltraSonic_command(); M_Disable(); } // 오른쪽 동작 void r_Stepping(){ M_move(H,L,L,H); delay(delay_time); // wait for a second M_move(H,H,L,L); delay(delay_time); // wait for a second M_move(L,H,H,L); delay(delay_time); // wait for a second M_move(L,L,H,H); delay(delay_time); // wait for a second } // 왼쪽 동작 void l_Stepping(){ M_move(L,L,H,H); delay(delay_time); // wait for a second M_move(L,H,H,L); delay(delay_time); // wait for a second M_move(H,H,L,L); delay(delay_time); // wait for a second M_move(H,L,L,H); delay(delay_time); // wait for a second } // 오른쪽 360도 -> 왼쪽 360도 void loop() { if(!flag){ r_Stepping(); if(deg < 52) deg = deg + 1; else flag = 1; } else { l_Stepping(); if(deg > 1) deg = deg - 1; else flag = 0; } } |
# 이후 숙제
- 시리얼로 받은 데이터로 윈도우에 그리기 (Visual Basic ?)
아두이노 나노 이용하여 자동 워킹인식 만들기... (어플속이기 ㅎ)
#include <Stepper.h>
// 1스텝 0.17578125도
// 2048 = 360도 // 1024 = 180도 //
#define STEPS 96 //128 //각도 16.87도
#define Speed (8192 / STEPS)*4 //안정적인 최고 스피드
// IN4 = 11 = 12
// IN3 = 10 = 11
// IN2 = 9 = 10
// IN1 = 8 = 9
// IN4, IN2, IN3, IN1
Stepper stepper(STEPS, 12, 10, 11, 9);
void setup() {
stepper.setSpeed(Speed);
}
void loop() {
stepper.step(STEPS);
stepper.step(-STEPS);
}