기본 콘텐츠로 건너뛰기

라벨이 Programming인 게시물 표시

RF24 한 모듈에서 Read/Write 하기

RF 통신을 사용하는 간단한 장비 개발을 진행하게 돼, 가장 가격이 낮기도 하고 보편화됀 2.4Ghz RF 모듈을 사용하기로 했다. 위 보드를 사용하기 위해서 RF24 라이브러리를 사용할때 기기마다 Write 하고 Read 하는 기기가 별도로 지정되어 있으면 별 문제가 없지만, 한 기기에서 Read/Write를 동시에 하는 경우에는 문제가 생긴다. RF24 radio ( 9 , 10 ) ; radio . openWritingPipe ( ADMIN_ADDRESS ) ; radio . openReadingPipe ( 1 , RELAY_ADDRESS ) ; radio . startListening ( ) ; if ( radio . available ( ) ) { uint8_t * packet = ( uint8_t * ) calloc ( sizeof ( uint8_t ) , PACKET_SIZE ) ; radio . read ( packet , PACKET_SIZE ) ; radio . writeFast ( packet , PACKET_SIZE ) ; delete [ ] packet ; } 위와 같이 RELAY_ADDRESS로 받은 신호를 받아서 ADMIN_ADDRESS로 보내주기만 하는 코드가 있다고 가정하자, 이 경우 RF24 라이브러리에서는 수신은 가능하지만 송신은 불가능한 문제가 있다. 이 경우 writeFast의 반환값이 3번 정도는 송신에 성공했다는 true값을 반환해서 문제점을 찾기가 어렵다.  해결법은 다음과 같다. RF24 radio ( 9 , 10 ) ; radio . openWritingPipe ( ADMIN_ADDRESS ) ; radio . openReadingPipe ( 1 , RELAY_ADDRESS ) ; radio . startListening ( ) ; if ( radio . available ( ) ) { uint8_t * p...

EF쏘나타 계기판 Project Cars 2 연동

테스트 사진 코로나 때문에 나가지도 못하고... 집에서하는 게임이랑 연동 되는 계기판을 만들어봤다. EF쏘나타 계기판이 속도 신호랑 RPM신호가 PWM신호로 들어가는데, 비슷한거 하실 분들은 이 CAN신호 보내면 되는 이후 모델 계기판으로 하시는걸 추천드립니다. (파형 hz구하는 식은 아래 코드 참조) template < typename T> uint32_t kmHToHz(T speed) { // 200 = 50hz auto test = static_cast < double >(speed); if (test > 240 ){ test = 240 ; } double speedHzOutput = test * 2.5 ; ESP_LOGI( "Speed" , "%lf hz" , speedHzOutput); return static_cast < uint32_t >(speedHzOutput); } template < typename T> uint32_t RPMToHz(T rpm) { // 1000 = 30.9hz auto test = static_cast < double >(rpm); if (test > 8000 ){ test = 8000 ; } double hz = test / 30 ; ESP_LOGI( "RPM" , "%lf hz" , hz); return static_cast < uint32_t >(hz); } 나중에 유로트럭이나 프카1 패킷에도 호환 시키려고 함수템플릿 적용

android -> androidx 전환시 오류 고치기

구글 IO 2018에서 발표된 JetPack은 기존의 'com.android.support.*' 라이브러리들을 통합한 라이브러리 라고 보면 편하다. 그래서 원래 있던 프로젝트들을 위와같이 바꿔주고 빌드를 하면... 짠. 버그가 발생한다. 프로젝트 맨위에 'gradle.properties' 파일에 아래내용을 추가해준다. android.useAndroidX=true android.enableJetifier=true   원래 Android Studio 버전이 3.2.0 이상이면 마이그레이션 기능을 지원하지만, 일일히 옮기면 저런 버그가 발생하니 주의!

C언어 register 변수의 함정카드

C언어를 하다보면 register 라는 CPU의 레지스터에 자료를 저장하는 변수를 알수있다. 대신에 한 프로그램에서 최대 2개 정도까지만 사용이 가능하고 지역변수만 가능 및 32bit CPU는 32bit 크기의 변수만 사용 가능하다. 장점만 보면 기본적으로 메모리쪽에 저장되는 일반 변수들보다 더 빠르게 접근이 가능할 것 같은데...인라인 어셈이랑 메모리랑 레지스터랑 비교하면 어떤게 가장 빠른지 궁금해서 한번 테스트 해보게 되었다. 우선 테스트 해볼 코드는 다음과 같다. 거의 동일한 연산을 하고 다른 점이 있다면 인라인 어셈은 전부 다 레지스터를 이용해서 연산한다는 정도...? 위의 코드를 컴파일 해서 실제로 돌려보면 실행 결과는 다음과 같이 나온다. !? 그냥 아무런 형식도 지정해주지 않은 auto와 똑같은 결과가 나온다. # C언어는 기본적으로 아무런 형식을 지정해주지 않으면 auto로 해준다. # int a => auto int a 그래서 어째서 저런 결과가 나왔는지 컴파일에 옵션을 줘서 어셈파일을 분석해 보았다. 인라인 어셈 auto for register for push ebp mov ebp, esp mov ecx, 0 jmp SHORT $INLoop$3 $INLoop$3: cmp ecx, 10000000 jae SHORT $EXIT$4 mov eax, ecx shl eax, 2 inc ecx jmp SHORT $INLoop$3 $EXIT$4: cmp ebp, esp call __RTC_CheckEsp popebp ret,0 push ebp mov ebp, esp sub esp, 8 mov DWORD PTR [ebp-8], -858993460 mov DWORD PTR [ebp-4], -858993460 mov DWORD PTR _i$2[ebp], 0 jmp SHORT $LN4@For $LN...

far, near 포인터

far, near 포인터는 예전 Dos 시절에 사용하던 포인터 들입니다. 16비트 메모리 환경에서 20비트 메모리 주소를 표현하기 위해서 사용되었습니다. 그 당시에는 메모리에 접근하기 위해서 오프셋(16bit)과 세그먼트(16bit)라는 것을 사용해서 예를 하나 들자면 F000 : 0001 (세그먼트 주소 : 오프셋 주소) = F0000001 (실제 주소) 이렇게 두 값을 더해서 메모리 주소를 표현 했습니다. near 포인터는 오프셋 포인터만을 저장할 수 있어 16 bit의 크기를 가지고 있습니다. far 포인터는 세그먼트 와 오프셋을 모두 저장이 가능하고 32bit의 크기를 가지고 있습니다. 그리고 huge 라는 포인터도 있는데 이 포인터는 오프셋을 저장하지만 far 포인터와는 다르게 오프셋의 값에 0 ~ 15까지의 값 만 넣을수 있다고 합니다. 이 주소를 사용하면 주기억 장치의 한 장소 중에서 주소가 딱 하나로 결정되는 장점이 있다고 하네요. 현재의 win32에서는 사라진 것으로 알려져 있으나 windows.h 에 아직 존재하기는 합니다. 아래와 같이 코드를 작성한후 돌리게 되면 아래 사진과 같은 결과를 얻을 수 있습니다. #include <stdio.h> #include <windows.h> void main(void) {     int far test = (int far)new int;     short near test2 = (short near)new short;     printf("far : %d\n", test);     printf("near : %d\n", test2);     system("pause"); } * 원래 정석대로면 farmalloc 등을 이용해서 할당을 하는게 맞긴 하지만 들어 있는 헤더를 찾지 못해서 new 로 비슷하게 구현...

Android Auto Naver Login (네이버 자동 로그인) - 2

(1편 부터 이어집니다.) 웹뷰에서 자바 스크립트설정이랑 쿠키도 끝낫으니 이제 요청헤더에 몇몇개의 값을 추가해줘야된다. 나중에 로딩할때         web.loadUrl(NAVER_LOGIN, extraHeaders);   이렇게 포함시켜주면 된다. 일단 요청헤더를 추가하기 위해서 Map<String, String> 형식으로 추가해준다.         Map<String, String> extraHeaders = new HashMap<String, String>();         extraHeaders.put("Referer", Config.HEADER_REFERERURI);         extraHeaders.put("ContentType", Config.HEADER_CONTYPE);         extraHeaders.put("User-Agent", Config.HEADER_UA); 대충 이렇게 설정해주는데 각각의 값은 다음과 같다. (코드에서 Ctrl + C, Ctrl + V라 좀 깁니다...) [Class Config]     public static final String HEADER_CONTYPE = "header_ConType = \"application/x-www-form-urlencoded\";";     public static final String HEADER_UA = "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:48.0) Gecko/...

Android Auto Naver Login (네이버 자동 로그인) - 1

# CAUTION # 시작하기 전에 이 방식은 약간의 편법 을 이용한 방식이고 안드로이드 4.4 이상 부터 지원하는 것을 알려둔다... (그리고 현재 라이브러리로 만드는 중) 사실 이 내용은 누군가의 부탁을 받아서 만들기 시작한건데, 다 완성도 되고 부탁한 애도 관련 일 다 끝낸거 같으니까 포스팅한다... 안드로이드에서 네이버 로그인을 위해서는 간단하게 네이버 API를 사용해서 로그인 하는 방식이 주로 보편적으로 이용된다. 위와 같은 api들이 있는데 네이버 메일을 파싱하거나 네이버 카페의 글 들을 파싱해야되는경우 API 가 없기 때문에 다른 방식을 사용해서 해야된다. 지금부터 그 과정중 가장 기본이되는 네이버 로그인부터 시작해보도록 한다. https://nid.naver.com/nidlogin.login 에서의 네이버 로그인 과정을 분석해보면 id, pw의 길이를 검사해서 입력햇는지 검사 입력되엇으면 http://static.nid.naver.com/enclogin/keys.nhn 또는 https://nid.naver.com/login/ext/keys.nhn 에 접속해서 랜덤 값을 가져온다 js 에서 RSA 암호화  특정 형식으로 POST 쿠키 받기 간략하게 이러한 과정을 거치는데... 내가 아는 한에서는 안드로이드에서는 js 를 돌릴수는 있지만 C# 처럼 자유롭게(?) 이용하는 것이 힘들다. 그래서 처음 선택한 방안이 HtmlUnit 이라는 것과 Sel..뭔 라이브러리가 있는데 여러개 전부 다 테스트를 해 보았지만 전부 작동이 되지를 않았다... 그래서 그냥 라이브러리 없이 진행하기로 했다. 일단 하는 방식은 간단하게 다음과 같다. 웹뷰를 이용해서 로그인 쿠키유지 엄청 간단하다. 그런데 이러한 의문이 들 수도 있다. Q1. 웹뷰를 쓰면 입력을 수동으로 해야될텐데, 그럼 자동이 아니잖아??? A. 웹뷰 써도 자동으로 할 수 있어! 이제 답을 말하자면 WebView에서 ID와 PW...

HomeNews Alpha Final!

그런데 인성인증인데 왜 기술적인걸로 프로젝트를 햇더라 파싱은 제리코 라이브러리를 사용해서 완성시켰다. 이제 PPT짜러...! 거의 다완성되간다!

홈뉴스 alpha V.2

  바뀐 홈뉴스 로고!  홈뉴스 V.2 예전에 문제된점은 없에고, UI개선 흡흡...

C의 volatile

가장 쓰이지 않는 C/C++ 언어의 volatile 이라는 키워드가 있다. 이 키워드는 대부분의 참고 서적들이 컴파일러의 최적화를 막아준다고만 적어둘 정도로 사용 빈도수가 적기도하고 중요도 까지도 낮은 그런 키워드인 셈이다. 하지만 이 키워드가 임베디드 소프트웨어 에서는 중요한 키워드중 하나가 된다. 거의 하드웨어가 사용하는 메모리 선언 시에 사용되고 다음과 같은 경우에 사용되는 편이다. 메모리 맵 입출력(MMIO)을 제어 인터럽트 서비스 루틴 사용 멀티 쓰레드 환경 이렇게 3가지에 사용되는데 임베디드에서는 주로 아래와 같은 예시들과 같은 경우에 주로 사용된다. 예시 1) unsigned int* test; test = (unsigned int*) 0x1020; test = (unsigned int*) 0x1028; 예를 들어서 다음과 같은 코드가 있을때 컴파일러는 중간 문장은 필요 없는 것으로 판단하고 제거한뒤 컴파일 할것이다. unsigned int* test; test = (unsigned int*) 0x1028; 결과 적으로는 위 문장만 실행되는데 volatile 키워드를 사용하면 이것들이 전부 컴파일 되서 전부의미를 가지게 된다 volatile unsigned int* test; test = ( volatile unsigned int*) 0x1020; test = ( volatile unsigned int*) 0x1028; 예시 2)  예를 들어 0x1234에 8비트의 status 레지스터가 있고, 이 레지스터가 0이 아닌 값을 가질때까지 폴딩하기 위해서 아래와 같은 코드를 작성했다. (루시퍼님 블로그의 예시가 적당해서 가져왔다) INT8U *ptr = (INT8U *)0x1234; while (*ptr == 0) 만약 옵티마이징을 키게 된다면 이것은 move ptr, #0x1234 move a, @ptr loop bz loop 이렇게 다시는 0x1234값을 받아오지 않게 어셈블...

2015년 인성인증 프로젝트 Home News

원래 이거 삼성 대회 나갈려고 준비한건데...아쉽지만 그래도 이렇게라도 만들게 되서 결과가 기대 된다...

C++ 더블링크드리스트

(내용 수정예정...)

C# AES

개인 프로젝트로 채팅쪽을 할생각이여서 통신할때 암호화 해서 보내면 좋지 않을까... 하고 만들어보게 되었다. 만들때 Form쓰는거에서 WPF로 바꾸면서, 코드는 Form때보다 긴데 그닥 예뻐지지 않은게 함정... (저 망할 Hint...)

C# GUI 진화 과정(?)

1 차 2 차 3차

C# GUI

 C# 은근히 재미가 있어서 GUI 를 도전해 봤다.... 음...뭔가 버튼이 투명하게 하고 GUI 코딩 실력 좀 돼서 이거 빨리 완성해서 가지고 놀고 싶다.