일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- thread
- 홈어시스턴트
- YMODEM
- raspberry
- 서버리스
- 파이썬
- Android
- IOT Core
- flask
- 전기차충전
- STM32
- 플라스크
- 안드로이드
- 완속충전기
- 전기차
- 라즈베리파이
- everon
- 급속충전기
- 전기차충전기
- AWS
- homeassistant
- lambda
- 펌웨어
- 에버온
- 충전기
- 보안
- OCPP
- dynamodb
- 디자인패턴
- esp8266
- Today
- Total
Louie NRT Story
[임베디드] 안드로이드 보드 Serial Port 통신 본문
작성일: 21년 10월 26일
PS. Smatek에서 제공하는 안드로이드 OS가 올라가는 ST-RK3288-01 보드를 이용하여 개발을 하고자 함
Index
1. Developer's Kit
2. android-serialport-api 오픈소스
3. SDK Tool 다운로드
4. 프로젝트 생성
5. Seriap Port 통신 환경 만들기
6. 코드 개발하기
1. Developer's Kit
1) SDK(Software Developer's Kit)
- Java기반으로 Application Level에서 개발을 쉽게 해주는 도구임
2) NDK(Native Developer's Kit)
- Application을 개발하는데 있어서 하드웨어에 직접 접근해야 하는 일이 발생하게 됨
- 효과적으로 개발을 위해서는 Java가 아닌 C/C++로 개발된 코드를 이용하게 됨
- Android Studio에서는 Java에서 호출을 하기 위한 동적 링크 라이브러리를 제공하는 NDK를 이용하여 컴파일을 하게 됨.
- C/C++을 개발하기 위해 NDK를 사용할때는 JNI 필수로 있어야함
3) PDK(Platform Developer's Kit)
- SDK와 NDK를 포괄하는 개념으로 Unix 계열의 OS에서 개발이 이루어지며 Android 전체 코드를 이용하여 개발함
- Linux Kernal Level과 그 위에 위치한 Native Library의 HAL 부분 등에 대해 개발을 함
2. android-serialport-api 오픈소스
- 아래의 코드를 다운로드함
- 9년전의 코드인데 지금도 쓰고 있다는게 참 대단함
3. SDK Tool 다운로드
- NDK와 컴파일에 필요한 CMake를 다운로드함
- Tools -> SDK Manager 클릭
- NDK와 CMake를 체크후 하단의 OK 버튼을 눌러 다운로드함
4. 프로젝트 생성
- File -> New -> New Project 클릭함
- Empty Activity를 선택함
- 프로젝트의 이름을 입력함
5. Seriap Port 통신 환경 만들기
1) 코드 복사하기
- 위에서 다운로드한 "android-serialport-api\project\src" 하위의 폴더 "android_serialport_api"를 java 폴더 하위에 복사함
2) 코드 복사하기
- android-serialport-api\project 하위에 jni 폴더와 libs 폴더를 프로젝트의 "main" 폴더 하위에 복사함
3) 컴파일할 파일 선택하기
- 프로젝트 우클릭하여 "Add C++ to Module" 클릭
- 복사한 jni 폴더 하위의 "Android.mk" 파일을 선택함
6. 코드 개발하기
- MainActivity 코드 입력
- SerialPort에게 연결할 포트와 보드레이트 정보를 입력함
- OutputStream을 이용하여 Byte 데이터를 전송함
- InputStream으로 데이터가 들어오면 OnDataReceived() 함수를 통하여 데이터를 읽게 됨
public class MainActivity extends AppCompatActivity {
private static final String LOG_TAG = "MainActivity";
protected SerialPort mSerialPort;
protected OutputStream mOutputStream;
private InputStream mInputStream;
private ReadThread mReadThread;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
mSerialPort = getSerialPort("/dev/ttyS1",115200);
mOutputStream = mSerialPort.getOutputStream();
mInputStream = mSerialPort.getInputStream();
/* Create a receiving thread */
mReadThread = new ReadThread();
mReadThread.start();
SendReadCardCommand();
}
catch (SecurityException e) {
Log.e(LOG_TAG,e.getMessage());
}
catch (InvalidParameterException e) {
Log.e(LOG_TAG,e.getMessage());
}
}
@Override
protected void onDestroy() {
if(mReadThread != null){
mReadThread.interrupt();
closeSeiralPort();
mSerialPort = null;
}
super.onDestroy();
}
byte bRcvBuf[] = new byte[1024];
int nOffset = 0;
protected void onDataReceived(final byte[] buffer, final int size) {
try {
System.arraycopy(buffer, 0, bRcvBuf, nOffset, size);
nOffset += size;
Log.d(LOG_TAG, "Offset: " + nOffset);
Log.d(LOG_TAG, "ReadResponse: " + byteArrayToString(bRcvBuf, nOffset));
bRcvBuf = null;
bRcvBuf = new byte[1024];
nOffset = 0;
} catch (Exception ex) {
Log.e(LOG_TAG, ex.getMessage());
}
}
private String byteArrayToString(byte[] a,int nSize) {
StringBuilder sb = new StringBuilder();
int nBreak = 0;
for(final byte b: a) {
sb.append(String.format("0x%02x ", b & 0xff));
nBreak++;
if(nBreak >= nSize){
break;
}
}
return sb.toString();
}
public void SendReadCardCommand(){
byte bSendVal[] = new byte[12];
bSendVal[0] = (byte)0x02;
bSendVal[1] = (byte)0x01;
bSendVal[2] = (byte)0xB0;
bSendVal[3] = (byte)0x01;
bSendVal[4] = (byte)0x0E;
bSendVal[5] = (byte)0x01;
bSendVal[6] = (byte)0xEA;
bSendVal[7] = (byte)0x00;
bSendVal[8] = (byte)0x00;
bSendVal[9] = (byte)0x48;
bSendVal[10] = (byte)0xDD;
bSendVal[11] = (byte)0x03;
try{
mOutputStream.write(bSendVal);
} catch (IOException ex){
Log.e(LOG_TAG, ex.getMessage());
}
}
private class ReadThread extends Thread {
@Override
public void run() {
super.run();
while (!isInterrupted()) {
int size;
try {
byte[] buffer = new byte[64];
if (mInputStream == null) return;
size = mInputStream.read(buffer);
if (size > 0) {
onDataReceived(buffer, size);
}
} catch (IOException e) {
e.printStackTrace();
return;
}
}
}
}
private SerialPort m_SerialRFID = null;
private SerialPort m_SerialCARD = null;
private SerialPort m_Serial = null;
public SerialPort getSerialPort(String strPortNum , int nBaudrate){
try {
if (m_Serial == null) {
m_Serial = new SerialPort(new File(strPortNum), nBaudrate, 0);
}
}
catch (Exception ex){
Log.e(LOG_TAG, ex.getMessage());
}
return m_Serial;
}
public void closeSeiralPort(){
if(m_Serial != null){
m_Serial.close();
m_Serial = null;
}
}
}
- Byte 단위로 읽은 데이터를 String으로 변환하여 로그에 찍도록 함.
Referece:
https://github.com/cepr/android-serialport-api
'전기차충전기' 카테고리의 다른 글
[안드로이드] 어플 아이콘 변경하기 (0) | 2021.11.02 |
---|---|
[Smatek] ST-RK3288-01 안드로이드 개발 환경 구축하기 (0) | 2021.11.01 |
[전기차 충전기] 에버온 (0) | 2021.10.16 |
[AWS] API Gateway Websocket - 02 (0) | 2021.10.10 |
[AWS] API Gateway Websocket - 01 (0) | 2021.10.04 |