728x90

메일 발송 조건

리눅스 CentOS 6 에서 sendmail 을 설치하고 관련 설정을 한 후 발송 테스트하고 적어둔다.

아래 코드는 회원 정보와 연동한 메일 발송 코드만 발췌한 것이다.

PHP는 자체적으로 메일을 발송하는 기능은 없다.

mail()함수는 메일 발송 폼을 작성하여 SMTP 서버로 전송해주는 역할을 한다.


<?php
$to = $email;
$from = "webmaster@abc.com";
$nameFrom = "AppMaster";

$subject = "비밀번호 변경";
$message ="<table>";
$message.="<tr>";
$message.= "<td>비밀번호는 암호화되어 있으므로, 회원님의 이메일 주소로 임시 비밀번호를 발급해 드립니다.</td>";
$message.="</tr>";
$message.="<tr>";
$message.= "<td>임시 비밀번호로 로그인 후, 반드시 새로운 비밀번호를 설정해 주십시요.</td>";
$message.="</tr>";
$message.="<tr>";
$message.= "<td>임시 비밀번호는  {$newPW}  입니다.</td>";
$message.="</tr>";
$message.="<tr>";
$message.= "<td>Web 사이트로 <a href='http://www.abc.com'>바로 이동</a> 하기</td>";
$message.="</tr>";
$message.="<tr>";
$message.= "<td>본 메일은 <font color=red>발신 전용</font>이라 수신이 불가능합니다.</td>";
$message.="</tr>";
$message.="</table>";

$mailheaders = "Return-Path: $from\r\n";
$mailheaders.= "From: $nameFrom <$from>\r\n";
$mailheaders.= "Content-Type: text/html;charset=utf-8\r\n";
$mailheaders.= "MIME-Version: 1.0\r\n";

mail($to, $subject, $message, $mailheaders, $from);
?>

블로그 이미지

Link2Me

,
728x90

jQuery 와 PHP 를 조합하여 로그인 실패시 접속시도 5회가 넘으면 접속을 차단하고, 관리자한테 문의하여 비밀번호를 초기화 요청할 수도 있고, 5분(지정시간) 경과후 다시 로그인을 시도할 수 있도록 하는 코드를 구현했다.


jQuery 함수만 적어둔다.


$('#login_submit').on('click',function(e){
    e.preventDefault();
    var userID = $('#loginID');
    var userPW = $('#loginPW');

    if(userID.val() ==''){
        alert('아이디를 입력하세요');
        userID.focus();
        return false;
    }

    if(userPW.val() ==''){
        alert('비밀번호를 입력하세요');
        userPW.focus();
        return false;
    }

    if(userPW.val().search(/\s/) != -1){
        alert("비밀번호는 공백없이 입력해주세요.");
        return false;
    }

    $.ajax({
        url:loginpath+'loginChk.php',
        type: 'POST',
        data: {
            userID:$("#loginID").val(),
            password:$('#loginPW').val()
        },
        dataType:'json',
        success:function(msg){
            switch(msg.result){
                case 0:
                    alert('입력한 정보를 다시 한번 확인하세요.');
                    break;
                case 1:
                case 2:
                    alert('로그인 '+msg.result+'회 실패했습니다');
                    break;
                case 3:
                case 4:
                case 5:
                    alert('로그인 '+msg.result+'회 실패했습니다\n 5회 틀릴 경우 접속이 차단됩니다.');
                    break;
                case 10:
                    alert('관리자가 로그인을 차단했습니다.');
                    break;
                case 11:
                    location.replace('index.php'); // 화면 갱신
                    break;
                case 12:
                    alert('가입 승인대기 중입니다.');
                    break;
                case 13:
                    alert('로그인 횟수 초과로 계정이 잠겼습니다.\n5분 후에 다시 로그인 하세요.');
                    break;
                case 21:
                    location.replace('index.php'); // 화면 갱신
                    break;
                default:
                    alert('다시 한번 확인하세요\n 에러메시지 : '+msg.result);
                    break;
            }
        },
        error: function(jqXHR, textStatus, errorThrown){
            alert("arjax error : " + textStatus + "\n" + errorThrown);
        }
    });

});
 


PHP 핵심 함수 코드이고 나머지 함수는 직접 구현하면 된다.

function LoginSuccessChk($userID,$password){ // Web 접속
    global $db;
    if(empty($userID) || empty($password)){
        return 0;
    } else {
        if($this->isUserExisted($userID) ==1){ // 가입된 userID가 존재하면
            if($this->PasswordChk($userID,$password) == 0){ // 패스워드 불일치
                // 1. access_failed_count 가 5 이상이면 access 를 3 으로 세팅한다.
                $rs = $this->updateAccountLock($userID);
                if($rs == 1){
                    // 3. DB에 저장된 시간과 현재 접속한 시간이 5분이 경과되면 자등으로 access=1 로 설정 변경한다.
                    $gaptime = $this->TimeDiffChk($userID);
                    if($gaptime == 1){
                        $this->clearAccountLock($userID);
                        return 0;
                    } else {
                        // 4. 5분이 경과되지 않았으면 메시지를 팝업한다.
                        return 13;
                    }
                } else {
                    // 2. access_failed_count 를 1 을 증가시킨다.
                    $this->plusLoginFailCount($userID);
                    return $this->LoginFailCountChk($userID); // 로그인 실패 횟수 반환
                }
            } else { // 패스워드 일치
                $rs = $this->AccessStatusChk($userID);
                if($rs == 11) { // 로그인 허용
                    // 1. access_failed_count 를 0 으로 초기화한다.
                    $this->clearLoginFailCount($userID);
                    // 2. access 를 1로 초기화한다.
                    $this->clearAccountLock($userID);
                    // 3. 접속일자 및 시간을 수정한다.
                    $this->AccessLog($userID,'');
                    return 11;
                } else if($rs == 13){
                    // DB에 저장된 시간과 현재 접속한 시간이 5분이 경과되면 자등으로 access=1 로 설정 변경한다.
                    $gaptime = $this->TimeDiffChk($userID);
                    if($gaptime == 1) {
                        $this->clearAccountLock($userID);
                        $this->AccessLog($userID,'');
                        return 11; // 로그인 허용
                    } else {
                        return 13; // 로그인 차단
                    }
                } else {
                    return $rs; // 10:불허, 12:승인대기, 13:차단
                }
            }
        } else {
            return 0; // 가입된 userID가 없으면
        }
    }
}


블로그 이미지

Link2Me

,
728x90

PHP 날짜와 시간 차이에 대한 테스트 결과다.

그냥 복사해서 테스트해보면 결과를 확인 할 수 있다.

 

<?php
date_default_timezone_set('Asia/Seoul');
$start = '2019-03-23';
$end = '2019-03-25';
$gap = DateDiff($start,$end);
echo '<pre>';print_r($gap);echo '</pre>';

echo DateDisplay( $gap->y, $gap->m, $gap->d).'<br />';
echo $gap->days.'일<br /><br />';

$curTime = date("Y-m-d H:i:s"); // 현재 날짜 및 시간
$access_date = "2019-03-26 09:56:22";

$date1 = strtotime($access_date);
$date2 = strtotime($curTime);
$gaptime = $date2 - $date1;

echo $gaptime.'<br />'; // 초단위 시간으로 반환
echo time_diff($access_date,$curTime).'<br />'; // 초단위 시간으로 반환

$seconds = $gaptime % 60;
$minutes = floor(($gaptime % 3600) / 60);
$hours = floor($gaptime / 3600);
echo $hours.":".$minutes.":".$seconds.'<br />';

$gap = DateDiff($access_date,$curTime);
echo $gap->format('%h:%i:%s').'<br /><br />';

echo '<pre>';print_r($gap);echo '</pre>';
echo DateDisplay( $gap->y, $gap->m, $gap->d).'<br />';

function DateDiff($startDate,$endDate){
    $date1 = new DateTime($startDate);
    $date2 = new DateTime($endDate);

    $gap = $date1->diff($date2);
    return $gap;
}

function DateDisplay($y,$m,$d){
    $gap ='Diff : ';
    if($y > 0) $gap.=$y."년 ";
    if($m > 0) $gap.=$m."월 ";
    $gap.=$d."일 ";
    return $gap;
}

function time_diff($datetime1, $datetime2) {
  return date('U',strtotime($datetime2))-date('U',strtotime($datetime1));
}
?>

 

 

로그인 시도 실패후 5분이 경과되면 다시 로그인을 할 수 있도록 만들기 위한 함수를 만들어 보자.

5분 = 300초 이므로

 

DB 테이블 칼럼에 저장된 시간을 $access_date = "2019-03-26 09:56:22";
이라 하고

현재 시간을 $curTime = date("Y-m-d H:i:s"); // 현재 날짜 및 시간

$gap = time_diff($access_date,$curTime); // 초단위 시간으로 반환

if($gap > 300){

   로그인 차단 설정을 허용으로 변경

} else {

   로그인 차단 메시지 팝업

}

블로그 이미지

Link2Me

,
728x90

MySQL DB 데이터를 csv 파일 형태로 저장하는 예제코드다.


<?php
$db['host'] = "localhost";
$db['name'] = "db명";
$db['user'] = "사용자id";
$db['pass'] = "비밀번호";
$db['port'] = "3306";
?>

<?php
include_once 'dbinfo.php';
$db = isConnectDb($db);

function isConnectDb($db)
{
    $conn = mysqli_connect($db['host'],$db['user'],$db['pass'],$db['name'],$db['port']);
    mysqli_set_charset($conn, "utf8"); 
    if (mysqli_connect_errno()) {
        echo "Failed to connect to MySQL: " . mysqli_connect_error();
        exit;
    } else {
        return $conn;
    }
}
?>

 <?php
$file_name = "cate_backup.xls";
header( "Content-type: application/vnd.ms-excel; charset=utf-8");
header( "Cache-Control: must-revalidate, post-check=0,pre-check=0" );
header( "Content-Disposition: attachment; filename=$file_name" );
header( "Content-Description: PHP4 Generated Data" );
//header() 함수를 쓰기전에 어떠한 출력도 있어선 안된다

include_once 'dbconect.php'; // DB 연동

$tblName = category;    // 테이블명
$sql ="SELECT uid, classname, relateduid FROM $tblName ORDER BY uid DESC";
// DESC 내림차순 정렬, ASC 오름차순 정렬
$result = mysqli_query($db,$sql);

// 테이블 상단 만들기
$EXCEL_STR = "
<table border='1'>
<tr>
<td align=center BGCOLOR='#9DEEE1'>번호</td>
<td align=center BGCOLOR='#9DEEE1'>구분자</td>
<td align=center BGCOLOR='#9DEEE1'>연관번호</td>
</tr>";

while ($row = mysqli_fetch_array($result) ){
    $EXCEL_STR .= "
    <tr>
    <td align=center>".$row['uid']."</td>
    <td align=center>".$row['classname']."</td>
    <td align=center>".$row['relateduid']."</td>
    </tr>
    ";
}

$EXCEL_STR .= "</table>";
echo $EXCEL_STR;
exit;
?>


블로그 이미지

Link2Me

,
728x90

csv 파일을 PHP를 이용하여 MySQL 에 업로드하는 예제코드다.

실전에서 활용하는 편리한 코드다.


<?php
error_reporting(0); // 경고 출력 방지, 주석처리해서 경고, 에러메시지 나오도록 하자.
require_once 'dbconnect.php';

date_default_timezone_set('Asia/Seoul');

// Edit upload location here
$tmpname    = $_FILES['file']['tmp_name'];
$realname    = $_FILES['file']['name'];

$fileExt    = getExt($realname);
$destination_path='uploads/';
$readFile = $destination_path . 'contactsdata.csv';

$errorFilename ="errorFile.txt";
$errorFile = $destination_path . $errorFilename;

$TABLENAME ='contacts'; // 테이블명

if (is_uploaded_file($tmpname)) {
    if (!strstr('[csv]',$fileExt)) {
        echo '<script type="text/javascript">alert("csv 파일만 등록할 수 있습니다.");</script>';
        exit;
    }
    move_uploaded_file($tmpname,$readFile);
    @chmod($readFile,0606);
}

/////////////////////////////////////////////////////////////////////////////////
$file_read = fopen($readFile,"r");
if(!$file_read){
    echo '<script type="text/javascript">alert("파일을 찾을 수가 없습니다!");</script>';
    echo "-2";
    exit;
}

// 파일 인코딩 모드 검사
$current_encoding = detectFileEncoding($readFile);
$total_line = 0;
$newcount = 0;
$upcount=0;
$ok = 0;

while($line = fgetcsv($file_read,1000, ";")) { // 구분자는 ; 로 지정
    // 파일 인코딩 모드 검사
    if($current_encoding != 'utf-8') {
        $line00 = iconv('euc-kr','utf-8',trim($line[0])); // 구분1(cat1)
        $line01 = iconv('euc-kr','utf-8',trim($line[1])); // 구분2(cat2)
        $line02 = iconv('euc-kr','utf-8',trim($line[3])); // officeNO
        $line03 = iconv('euc-kr','utf-8',trim($line[4])); // mobileNO
    } else {
        $line00 = trim($line[0]); // 구분1(cat1)
        $line01 = trim($line[1]); // 구분2(cat2)
        $line02 = trim($line[3]); // officeNO
        $line03 = trim($line[4]); // mobileNO
    }

    $cat1NM = $line00;
    $cat2NM = $line01;
    $officeNO = isset($line02) ? TelNumSplitRemove($line02) : '';
    $mobileNO = isset($line03) ? TelNumSplitRemove($line03) : '';

    $total_line++;
    if(strlen($mobileNO)<1) continue;

    // 구분1 코드 구하기
    $CA1= getDbData('category','name="'.$cat1NM.'" and parent_id=0','id');
    $cat1 = $CA1['id'];

    // 구분2 코드 구하기
    if(strlen($cat2NM)>0){
        $CA2= getDbData('category','parent_id="'.$cat1.'" and name="'.$cat2NM.'"','id');
        $cat2 = $CA2['id'];
    } else {
        $cat2 =0;
        continue; // 상황에 따라 체크 필요한 코드
    }

    $d_regis = date('Ymd');

    // 중복 등록 여부 검사
    $cnt = DataExistedChk($cat1,$cat2);
    if($cnt == "0"){
        $d_regis = date('Ymd');
        $QKEY = "cat1,cat2,officeNO,mobileNO";
        $QVAL = "'$cat1','$cat2','$officeNO','$mobileNO'";
        $rs = getDbInsert('contacts',$QKEY,$QVAL);
        $newcount++;
    } else {
        $QSET="officeNO='".$officeNO."',";
        $QSET.="mobileNO='".$mobileNO."'";
        $QVAL="cat1='".$cat1."' and cat2='".$cat2."' ";

        getDbUpdate('contacts',$QSET,$QVAL);
        $upcount++;
    }

    $ok ++;
    if (($ok % 500) == '0') {
        echo(" $ok 건 저장");
        flush();
        sleep(2); //500개 저장할때마다 2초씩 쉰다.
    }
} // while 문 종료
fclose($file_read);
unlink($readFile);  // 업로드 완료후에 파일 삭제 처리

$msg = '전체'.number_format($total_line).'건中 신규'.number_format($newcount).'건, 갱신'.number_format($upcount).'건 등록완료';
echo "<script type=\"text/javascript\">alert('$msg');</script>";

function getExt($filename){
    $ext = substr(strrchr($filename,"."),1);
    $ext = strtolower($ext);
    return $ext;
}

function detectFileEncoding($filepath) {
    // 리눅스 기본 기능을 활용한 파일 인코딩 검사
    $output = array();
    exec('file -i ' . $filepath, $output);
    if (isset($output[0])){
        $ex = explode('charset=', $output[0]);
        return isset($ex[1]) ? $ex[1] : null;
    }
    return null;
}

// ID Exist Check
function DataExistedChk($cat1,$cat2){
    global $db;
    $sql = "select count(*) from contacts where cat1='".$cat1."' and cat2='".$cat2."'";
    $result = mysqli_query($db,$sql);
    if($row = mysqli_fetch_row($result)){
        return $row[0];
    } else {
        return "0";
    }
}

//DB삽입
function getDbInsert($table,$key,$val){
    global $db;
    $sql ="insert into ".$table." (".$key.")values(".$val.")";
    if(mysqli_query($db,$sql)){
        return 1;
    } else {
        return 0;
    }
}

//DB업데이트
function getDbUpdate($table,$set,$where){
    global $db;
    mysqli_query($db,'set names utf8');
    mysqli_query($db,'set sql_mode=\'\'');
    $sql ="update ".$table." set ".$set.($where?' where '.getSqlFilter($where):'');
    if(mysqli_query($db,$sql)){
        return 1;
    } else {
        return 0;
    }
}

//SQL필터링
function getSqlFilter($sql)    {
    return $sql;
}


function TelNumSplitRemove($tel){
    return preg_replace("/[^0-9]/", "", $tel);    // 숫자 이외 제거
}
?>


블로그 이미지

Link2Me

,
728x90

PHP 로 jQuery 와 AJAX를 이용해서 파일을 업로드하는데 한참 삽질을 하고 적어둔다.

어쩌다 필요해서 하려고 하면 생각도 안나고 다시 제자리 걸음을 반복하는 초보자의 길을 언제나 벗어나려나 ㅠㅠ


MDB(Meterial Design Bootstrap) 기반 템플릿을 활용하여 코딩을 하느라고 class 가 이상것이 보이는 것이니 혹시라도 이 게시글을 읽으시는 분은 그냥 그런게 있나보다 하고 참조만 하시라.


파일 전송 Form 파일

<form id="uploadphoto" action="MemberPhotoUpload.php" method="post" enctype="multipart/form-data">
    <div class="card border-light mb-3" style="max-width: 30rem;">
      <div class="card-body text-dark">
        <h5 class="card-title">Image File Upload</h5>
        <input type="file" id="file" name="file" multiple />
        <input type="submit" value="Upload Photo" class="btnSubmit" />
      </div>
    </div>
</form> 

<table class='table table-responsive-sm' id='photoIDX' uid='<?php echo $idx;?>'>
    <tr><td colspan='5'>★★사진 등록시 [등록하기] , 사진 수정시 [사진을 클릭]하세요.</td></tr>
    <tr>
        <td rowspan='3'>
        <?php
            if(file_exists($imgpath)){
                echo "<img src='MemberPhotoView.php?idx=$idx&uid=$uid' width=115 height=140>";
            } else {
                echo "사진없음<br><span class='btn-floating peach-gradient photoBtn'><i class='fas fa-image'></i>등록하기</span>";
            }
        ?>
        </td>
        <th>아이디</th>
        <td><?php echo $row['userID'];?></td>
        <th>사무실번호</th>
        <td style='text-align:left;height:15px;'><?php echo $row['telNO'];?></td>
    </tr>
    <tr>
        <th>성명</th>
        <td><?php echo $row['userNM'];?></td>
        <th>휴대폰번호</th>
        <td style='text-align:left;height:15px;'><?php echo $mobileNO;?></td>
    </tr>
    <tr>
        <th>직위</th>
        <td><?php echo $chargeArr[$row['codeID']];?></td>
        <th>주업무</th>
        <td style='text-align:left;height:15px;'><?php echo $row['workrole'];?></td>
    </tr>
    <tr>
        <th>E-Mail</th>
        <td colspan='4' style='text-align:left;height:15px;'><?php echo $row['email'];?></td>
    </tr>
</table>


Script 파일

<script>

 $('.photoBtn').click(function(){
    var $obj=$(this);
    var idx=$(this).closest('#photoIDX').attr('uid');

    $('#dialog').load('MemberPhotoForm.php?idx='+idx, function() {
        $(this).dialog({
            autoOpen : true,
            height : 'auto',
            width : 'auto',
            position: { my: "center", at: "center", of: window },
            title : '사진 업로드',
            buttons : {
                "닫기" : function() {
                    $(this).dialog("close");
                }
            }
        });
        PhotoUploadChk(idx);
    });

});

function PhotoUploadChk(idx){
    $('form#uploadphoto').submit(function(e){
        e.preventDefault();
        var formData = new FormData();
        var files = $('#file')[0].files[0];
        formData.append('file',files);
        formData.append('uid',idx);

        formData.append('osType',$('select[name=osType]').val());

        var upfiles_cnt = $("input:file", this)[0].files.length;
        if(upfiles_cnt == 0){
            alert('선택된 파일이 없습니다.');
            return false;
        }

        $.ajax({
            url: 'MemberPhotoUpload.php',
            data: formData,
            cache: false,
            contentType: false,
            processData: false,
            type: 'post',
            success: function (msg) {
                if(msg == 1){
                    MemberView(idx);
                } else if(msg == 0){
                    alert('form 데이터 오류인지 확인하세요.');
                } else {
                    alert('파일이 업로드되지 못했습니다.');
                }
            }
        });

    });

}
</script>


PHP 파일 업로드 관련 파일

<?php
if(isset($_POST['uid']) && $_POST['uid']>0){
    $idx=$_POST['uid'];

    $tmpname    = $_FILES['file']['tmp_name'];
    $realname    = $_FILES['file']['name'];
    $fileExt    = getExt($realname);

    $file_path='./photos/'.$idx.'.jpg';

    if (is_uploaded_file($tmpname)) {
        if (!strstr('[jpg]',$fileExt)) {
            echo "-1";
            exit;
        }
        move_uploaded_file($tmpname,$file_path);
        @chmod($file_path,0606);
        echo "1";
    }
} else {
    echo "0";
}

function getExt($filename){
    $ext = substr(strrchr($filename,"."),1);
    $ext = strtolower($ext);
    return $ext;
}
?>


파일 사이즈 검사하여 파일 사이즈를 줄이는 코드는 포함되지 않았다.


$("#uploadbutton").click(function(){
    var form = $('form')[0]; // 폼객체를 불러와서
    var formData = new FormData(form); // FormData parameter 에 담아줌
    $.ajax({
        url: 'fileupload',
        processData: false,
        contentType: false,
        data: formData,
        type: 'POST',
        success: function(result){
            alert("업로드 성공!!");
        }
    });
});

블로그 이미지

Link2Me

,

테이블명 변경

SQL 2019. 3. 11. 13:39
728x90

phpMyAdmin 에서 테이블명 변경을 했더니 아래와 같은 방식으로 처리가 된다.


CREATE TABLE `helpdesk`.`positionMN` (

`codeID` int( 10 ) unsigned NOT NULL DEFAULT '0',
`codeNM` varchar( 40 ) DEFAULT NULL ,
PRIMARY KEY ( `codeID` )
) ENGINE = MYISAM DEFAULT CHARSET = utf8;

INSERT INTO `help`.`positionMN`
SELECT *
FROM `help`.`PositionMN` ;

DROP TABLE `help`.`PositionMN` ;


'SQL' 카테고리의 다른 글

MySQL DB 백업  (0) 2020.06.13
SQL 테이블 칼럼 추가/삭제 방법  (0) 2020.03.14
MySQL 사용자 권한 부여  (0) 2018.11.26
MySQL 두 테이블 불일치 데이터 찾는 SQL  (0) 2018.08.18
Toad for MySQL - Database Diagram  (0) 2017.06.02
블로그 이미지

Link2Me

,
728x90

안드로이드는 USB 통신을 위한 두가지 모드를 제공 : Host Mode, Accessory Mode


Host mode : 안드로이드 기기가 USB 호스트가 되어 장치에 전원을 공급하는 모드이다.
이 모드를 사용하려면 안드로이드 기기가 OTG를 지원해야 하고 OTG 케이블이 별도로 필요하다.
Android USB Host 모드는 안드로이드 3.1 이상에서 지원
Host 안드로이드 장비는 USB host로서의 역할을 수행하고 전력을 공급하며 연결된 USB 장비를 열거한다.


Interface와 Endpoint를 취득하여만 실제적으로 USB 통신을 진행할 수 있다.

- UsbManager, UsbDevice : device를 받고
- UsbInterface, UsbEndpoint : interface와 endpoint 를 찾고
- UsbDeviceConnection : 연결한다.


bulkTransfer() : 파라미터로 전달되는 Endpoint 방향에 따라서 Bulk Data의 송/수신 작업을 수행
controlTransfer() :  Endpoint Zero(0)로 Control Data의 송/수신 작업을 수행

Accessory mode : 안드로이드 기기가 주변기기가 되고 연결되는 USB 장치가 호스트가 되는 모드이다.


케이블을 구매할 때 별도의 전원이 공급되어야만 동작되는 케이블은 Accessory mode 로 동작한다고 보면 된다.

별도의 전원 공급없이 동작되는 케이블을 구입하는 것이 좋다.


모든 USB 장치는 Vendor ID 와 Product ID를 갖고 있다. 이 두개의 값으로 장치의 종류를 구분할 수 있다.


검색하면 "아두이노와 안드로이드" 연결에 대한 게시글들이 검색된다.

Android Serial 통신 소스코드는 https://github.com/godstale/Arduino-Serial-Controller 를 다운로드 한다.

usbSerialForAndroid 에 코드는 프로젝트에 별도 폴더로 옮기고 import 는 상황에 맞게 수정한다.

소스코드는 수정하지 않고, import 만 변경한다.


arduinocontroller 코드에 나온 4개의 파일을 약간 수정한다.

ArduinoControllerActivity.java 파일 수정

 - OTG Cable이 연결되면 자동으로 찾도록 BroadcastReceiver mUsbDeviceReceiver = new BroadcastReceiver() 에 대한 코드를 구글 검색하여 추가한다.

- Scrollview 시 키보드 입력에 따라 화면이 자동으로 변경되도록 코드를 추가한다.

  https://link2me.tistory.com/1613 게시글에 테스트한 코드를 참조하면 도움된다.

- https://android-er.blogspot.com/2014/03/android-send-command-to-arduino-in-usb.html 게시글을 참조하여

  두 게시글의 코드를 조합하여 만들면 원하는 결과를 얻을 수 있을 것이다.

- 나머지는 구글 플레이 스토어에서 USB Console 을 검색하여 앱을 사용해보고 원하는 기능을 추가한다.

- 핸들러 개념은 https://link2me.tistory.com/1233 참조한다. 좀 부족할 수 있다.

  https://zbomoon.tistory.com/10 참조

  링크된 예제에 구현된 handler 만으로도 충분히 원하는 결과를 얻을 수 있다.


SerialConnector.java 파일 수정

- UsbSerialDriver mDriver, UsbSerialPort mPort 는

   usbSerialForAndroid의 driver 파일과 연관되어 있으므로 모두 ArduinoController 폴더로 복사한다.

- public class SerialMonitorThread extends Thread 내 void run() 코드 중에서

  // Extract data from buffer 부분은 콘솔용으로 사용시에는 별 필요가 없다.

  SerialCommand.java 의 public void addChar(char c) 부분을 약간 수정한다.

public class SerialMonitorThread extends Thread {
    // Thread status
    private boolean mKillSign = false;
    private SerialCommand mCmd = new SerialCommand();

    private void initializeThread() {
        // This code will be executed only once.
    }

    private void finalizeThread() {
    }

    // stop this thread
    public void setKillSign(boolean isTrue) {
        mKillSign = isTrue;
    }

    /**
     *    Main loop
     **/
    @Override
    public void run() {
        byte readBuffer[] = new byte[4096]; // 아두이노 128

        while(!Thread.interrupted()) {
            if(sPort != null) {
                Arrays.fill(readBuffer, (byte)0x00);

                try {
                    // Read and Display to Terminal
                    int numBytesRead = sPort.read(readBuffer, 2000);
                    if(numBytesRead > 0) {
                        Log.d(tag, "run : read bytes = " + numBytesRead);

                        // Print message length
                        Message msg = mHandler.obtainMessage(Constants.MSG_READ_DATA_COUNT, numBytesRead, 0, new String(readBuffer));
                        mHandler.sendMessage(msg);

                    } // End of if(numBytesRead > 0)
                }
                catch (IOException e) {
                    Log.d(tag, "IOException - sDriver.read");
                    Message msg = mHandler.obtainMessage(Constants.MSG_SERIAL_ERROR, 0, 0, "Error # run: " + e.toString() + "\n");
                    mHandler.sendMessage(msg);
                    mKillSign = true;
                }
            }

            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
                break;
            }

            if(mKillSign)
                break;

        }    // End of while() loop
        // Finalize
        finalizeThread();
    }    // End of run()
}    // End of SerialMonitorT



나중에 기회되면 https://github.com/felHR85/UsbSerial 를 테스트 해보련다.


'안드로이드 > Android Serial 통신' 카테고리의 다른 글

usbDeviceConnection.controlTransfer  (0) 2019.04.27
Log 파일로 저장하는 코드  (0) 2019.04.25
ScrollView 데이터 자동 화면 표시  (0) 2019.02.19
Android USB Host  (0) 2019.02.15
UART 와 RS232C 개념 이해  (2) 2019.02.14
블로그 이미지

Link2Me

,