일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 통근버스 출발 순서 검증하기
- 사물인식 최소 면적 산출 프로그램
- 코테기출
- Sparkfun Edge 프로젝트
- Spakrfun Edge
- Sparkfun Edge Example
- c언어 static
- softeer
- c언어 라이프타임
- Python
- GStreamer
- c언어 지역변수
- C++
- nodejs 기초
- MacOS 설치
- 지도 자동 구축
- C++해설
- GStreamer tutorial
- GStreamer 튜토리얼
- SKT FLYAI
- 소프티어
- 성적평균
- 수퍼컴퓨터 클러스터
- c언어 정적변수
- 삼성전자 #영상디스플레이사업부 # VD사업부 #면접후기
- 플레이페어 암호
- 삼성 B형
- c언어 전역변수
- c언어 스코프
- 코딩테스트 기출
- Today
- Total
mulll
[Sparkfun Edge] Himax - HM01B0 카메라를 이용한 Snap Shot 찍기 본문
재미있어 보이는 Sparkfun Edge 카메라 관련 예제 프로젝트가 있어서 실행해 보았고 실행과정 및 실행 도중 해결한 문제점을 위주로 포스팅을 통해 정리하고자 한다. Himax 카메라가 읽은 프레임을 호스트 PC에 비트맵 형식으로 Serial 유선전송하는 간단하지만 새로운 프로젝트 수행에 기반이 되는 흥미로운 프로젝트인 것 같다.
개발 OS: Ubuntu 20.04.3 LTS / 64-bit
하드웨어 구성
SparkFun Edge Development Board - Apollo3 Blue | Himax CMOS Imaging Camera - HM01B0 | Reversible USB A to C Cable - 2m | SparkFun Serial Basic Breakout - CH340C and USB-C |
0. Arduino IDE 설치 및 실행
https://www.arduino.cc/en/software
Linux AppImage 64 bits 를 선택을 하고 다운로드한다.
다운로드한 파일을 우클릭하여 속성 -> Allow excuting file as program을 체크해 준다.
이후 다운로드한 파일을 더블클릭하여 실행해 준다.
실행화면이 나타나게 된다.
1. Arduino ide 환경설정 및 라이브러리 설치
- File -> Settings -> Additional boards manager URLs 칸에 아래의 URL을 추가한다.
- Tools -> Manage Libraries에서 himax 검색 후 아래의 해당 라이브러리를 설치한다.
- Tools -> Board -> Boards Manager에서 apollo3 검색 후 아래의 보드 패키지를 설치한다.
- Bootloader는 Default인 Ambiq Secure Bootloader를 선택한다. 다른 부트로더로 선택가능한 Sparkfun Variable Bootloader로 업로드를 계속 시도해 보았지만 잘 안된다...
- Tools -> Ambiq Secure Bootloader Baud Rate는 921600 인지 확인한다.
- Tools -> SVL Baud Rate는 460800 인지 확인한다.
- Tools -> Programmer 가 Ambiq Secure Bootloader 인지 확인한다.
2. Example 코드 불러오기
다음은 Himax 라이브러리의 Example을 불러올 것이다.
File -> Examples -> Sparkfun Himax HM01B0 Camera -> Sparkfun_Edge -> Example1_StopMotion을 클릭하면 새로운 창이 나타나게 되며 Example 코드가 나타난다. 한 프레임이 완성되면 Serial Port로 프레임을 전송하는 코드이다.
3. 프로젝트 코드 살펴보기
- 프로젝트의 코드를 살펴보자. 먼저 setup 과 loop 함수가 큰 틀을 구성한다. 함수명에서도 알 수 있듯이 setup 함수는 프로세스 실행 시 가장 처음 실행되는 함수이며 loop 함수는 프로세스가 종료될 때가지 무한히 반복하는 구조로 함수의 내부를 구현함으로써 보드의 기능을 SW적으로 설계할 수 있다.
void setup() {
...
}
void loop() {
...
}
- setup 부분은 아래와 같이 구현되어있다. 시리얼 포트 설정을 하고, 카메라 켈리브레이팅 및 파이썬 스크립트와 동기화를 하는 단계이다.
void setup() {
// 460800의 BAUD RATE로 시리얼 포트 연결 후 SERIAL_PORT가 활성화 될때까지 대기
SERIAL_PORT.begin(BAUD_RATE);
do {
delay(500);
}while(!SERIAL_PORT);
// Turn on camera regulator if using Edge board
#if defined (ARDUINO_SFE_EDGE)
pinMode(AM_BSP_GPIO_CAMERA_HM01B0_DVDDEN, OUTPUT);
digitalWrite(AM_BSP_GPIO_CAMERA_HM01B0_DVDDEN, HIGH);
SERIAL_PORT.println("Turned on Edge camera regulator");
#endif
// Start the camera
if(myCamera.begin() != HM01B0_ERR_OK){
SERIAL_PORT.print("Camera.begin() failed with code: " + String(myCamera.status) + "\n");
}else{
SERIAL_PORT.print("Camera started successfully\n");
}
// Calibrate Autoexposure
SERIAL_PORT.println("Calibrating Auto Exposure...");
myCamera.calibrateAutoExposure();
if(myCamera.status != HM01B0_ERR_OK){
SERIAL_PORT.println("\tnot converged");
}else{
SERIAL_PORT.println("\tconverged!");
}
#ifdef DEMO_HM01B0_TEST_MODE_ENABLE
// Enable test mode (generates a 'walking 1s' pattern to verify interface function
SERIAL_PORT.print("Enabling test mode...\n");
myCamera.enableTestMode();
if(myCamera.status != HM01B0_ERR_OK){
SERIAL_PORT.print("\tfailed\n");
}else{
SERIAL_PORT.print("\tsucceeded!\n");
}
// In test mode capturing a frame fills the buffer with the test pattern
myCamera.capture();
uint32_t mismatches = myCamera.countTestMismatches();
SERIAL_PORT.print("Self-test mismatches: 0x");
printWord(mismatches);
SERIAL_PORT.print("\n");
#endif
SERIAL_PORT.write(0x55); // 나중에 실행할 파이썬 스크립트와 맞춰주기 위한 특수값 전송
SERIAL_PORT.print("\n\n"); // Newlines allow Python script to find frame start
}
- loop 부분은 아래와 같다.
void loop() {
// Take an image
myCamera.capture();
#ifdef DEMO_HM01B0_FRAMEBUFFER_DUMP_ENABLE
// Print out a frame for the Python script to pick up
framebuffer_dump();
#else
// Print auto exposure state
SERIAL_PORT.print("AE convergance(0x");
printByte(myCamera.aeConvergenceStatus);
SERIAL_PORT.print(") TargetMean 0x");
printByte(myCamera.aecfg.ui8AETargetMean);
SERIAL_PORT.print(", ConvergeInTh 0x");
printByte(myCamera.aecfg.ui8ConvergeInTh);
SERIAL_PORT.print(", AEMean 0x");
printByte(myCamera.aecfg.ui8AEMean);
SERIAL_PORT.print("\n");
#endif
}
- framebuffer_dump 함수
// frame buffer dump (formatted for python script)
void framebuffer_dump( void ){
SERIAL_PORT.print("+++ frame +++"); // Mark frame start
for (uint32_t ui32Idx = 0; ui32Idx < myCamera.frameBufferSize; ui32Idx++){ // Process all bytes in frame
if ((ui32Idx & 0xF) == 0x00){ // Print address every 16 bytes
SERIAL_PORT.print("\n0x");
printWord(ui32Idx);
SERIAL_PORT.print(" ");
}
printByte(myCamera.frameBuffer[ui32Idx]); // Print byte value
SERIAL_PORT.print(" ");
}
SERIAL_PORT.print("\n--- frame ---\n");
memset(myCamera.frameBuffer, 0x00, sizeof(myCamera.frameBufferSize)); // Zero out frame buffer for help identifying errors
}
4. 포트설정
하드웨어를 완성한 뒤 PC에 부착한다. linux의 경우 /dev/ttyUSB* 으로 Sparkfun Edge가 인식된다.
업로드 버튼 옆의 Unknown을 클릭한 뒤 아래와 같이 Sparkfun Edge를 검색해서 연동한다.
5. 검증 및 업로드
- Tools-> Burn Bootloader를 실행한다.
- 체크 표시가 되어있는 Valifiy 버튼을 눌러 컴파일을 수행한다.
완료 시 아래와 같이 할당될 메모리정보와 기타 등등이 보인다.
- 화살표 표시의 Upload를 수행하기 전
Sparkfun Edge의 14 버튼과 RST 버튼이 존재한다. 14 버튼을 누른 채 RST버튼을 누르고 땐다. 그 이후 upload버튼을 누른다. 이때 주의할 점은 14 버튼은 업로드가 끝날 때까지 계속 누르고 있어야 한다는 것이다.
이후 아래와 같이 화면이 나오면 성공한 것이다.
에러 대응 1. no upload port provided 가 출력 시
위 에러를 마주쳤다면 Permission 문제일 가능성이 크다.
Permmision 문제일 경우 아래와 같이 권한 설정을 해준 뒤 다시 업로드 과정을 수행한다.
sudo chmod 777 ${연결된 디바이스의 경로}
# 본인의 경우
sudo chmod 777 /dev/ttyUSB0
6. Util App 실행
Sparkfun Board 쪽의 업로드 및 설정은 모두 마쳤으므로 리눅스 쪽에서 스냅숏을 받기 위해 설정해주어야 할 차례다. 라이브러리의 location을 임의로 바꾸지 않았다면 설치된 아두이노 IDE의 라이브러리는 아래의 PATH에서 확인할 수 있다.
dongha@my-laptop:~$ cd ~/Arduino/libraries/
dongha@my-laptop:~/Arduino/libraries$ ls
Arduino_TensorFlowLite SparkFun_Himax_HM01B0_Camera
이후 아래의 경로로 다시 한번 이동한다.
cd SparkFun_Himax_HM01B0_Camera/utils/
이후 다음 명령어를 수행한다.
sudo python3 Example1_StopMotion.py -o . -p /dev/ttyUSB0
시리얼 포트를 통해 전송된 프레임이 모여서 쌓이게 되면 비트맵 형식의 이미지를 주기적으로 보여준다.
에러 대응 2. no module named "serial"가 출력 시
계속해서 설치했음에도 없는 모듈이라고 나타나서 sudo 명령어를 붙여서 설치해 보니 잘 되었다. 아마 권한 문제였던 것 같다.
sudo pip3 install pyserial
7. 실행 결과
주기적으로 카메라로부터 받은 프레임이 전송되어 호스트 pc에 전송해 준다.
8. 이후 공부하고 싶은 것들
Tensorflow lite 의 CNN 모델 기반 Object Classification 과 같은 고급 영역까지 공부해서 Sparkfun Edge 보드 위에 올려보고 싶다.