'분류 전체보기'에 해당되는 글 335건
- 2017.09.19 Hardware | TSSR 3.5mm audio jack 구매하기
- 2017.09.19 Hardware | Adafruit SSD1306 128x64 1.3" monochrome OLED 를 사용해보자
- 2017.09.14 Hardware | SSD1306 128x64 monochrome OLED 를 사용해보자
- 2017.09.14 Software | FFmpeg 를 사용하여 동영상을 회전시켜 보자
- 2017.09.07 Hardware | SSD1331 96x64 full color OLED 를 사용해보자
- 2017.09.05 Software | u-blox 의 GPS 어플을 사용해 보자
- 2017.09.05 Hardware | FTDI Serial Adapter 를 사용해 보자
- 2017.09.05 Hardware | NEO-6M GPS 를 구동해 보자 2
- 2017.09.01 Software | Visual Studio Code 를 사용해 보자
- 2017.08.30 Software | IntelliJ IDEA 를 사용해 보자
1. Safecast bGeigie Nano
시간이 나면, 짬짬이 방사능 측정기를 조립하고 있습니다.
- http://chocoball.tistory.com/entry/Hardware-Safecast-bGeigie-Nano-1
조립 메뉴얼을 보면,
option 으로 분류되어 있으며 구성품에 포함되어 있지 않은 부품이 한개 있습니다.
- https://github.com/Safecast/bGeigieNanoKit/wiki/Assembly-Manual
이는 "TSSR 3.5mm audio out jack" 으로,
부착하고 싶으면 따로 구매를 해야 합니다.
부품리스트에서 자세히 보면, 아래 제품이라는 것을 알 수 있습니다.
* SparkFun TRRS 3.5mm Jack Breakout
- https://www.sparkfun.com/products/11570
bGeigie Nano 구매하고 구성품 받기까지 오래 걸리기도 하거니와
배대지를 이용해야 해서 여간 복잡한게 아니였습니다.
완성도 있게 만들고 싶은데, 이 부품이 빠지면 아쉬울 것 같아, AliExpress 도와줘요~ 해봅니다.
2. TSSR 3.5mm Audio Socket Breakout
AliExpress, 아니 중국은 대단한것 맞습니다.
완벽히 똑같은 카피품을 판매하고 있네요.
모양, pin 이름, 크기 모두가 똑같습니다.
여기에 더하여 가격이 1/4 가격입니다.
정품은 3.95 USD, 카피품은 1.09 USD 에 더하여 배송비 무료 입니다.
저같이 돈은 없지만, 전자부품으로 놀고 싶은 사람에게는 AliExpress 는 천국입니다.
3. 도착
아래는 도착샷 입니다.
평범하게 도착했습니다. 한 3주 걸린것 같아요.
앞면입니다.
프린트된 문구도 같네요.
뒷면입니다. TRRS Breakout 보드라고 표시되어 있네요.
4. 테스트
OLED 를 가지고 VU meter 를 만들어 볼 때, 테스트 해봤습니다.
- http://chocoball.tistory.com/entry/Hardware-VU-meter-using-SSD1306-monochrome-OLED
Arduino 와의 연결에, Male Pin 납땜을 하고싶지 않아서 Probe Clip 을 사용하였습니다.
- http://chocoball.tistory.com/entry/Hardware-Probe-Clip
여기서는 VU meter 를 구성하는 과정은 생략하고 결과만 올립니다.
iPhone 과 연결에 문제가 없네요.
확인 동영상 입니다.
FIN
방사능 측정기는 언제 조립을...
'Hardware' 카테고리의 다른 글
Hardware | Magnetic Charging Cable 을 구매해 보자 (0) | 2017.09.25 |
---|---|
Hardware | SSD1306 monochrome OLED 를 가지고 VU meter 를 만들어보자 (0) | 2017.09.19 |
Hardware | Adafruit SSD1306 128x64 1.3" monochrome OLED 를 사용해보자 (0) | 2017.09.19 |
Hardware | SSD1306 128x64 monochrome OLED 를 사용해보자 (0) | 2017.09.14 |
Hardware | SSD1331 96x64 full color OLED 를 사용해보자 (0) | 2017.09.07 |
1. OLED display
지금가지 AliExpress 에서 쉽게 구할 수 있는 0.95 ~ 0.96 inch 짜리 OLED display 를 가지고 놀았습니다.
* SSD1306 128x64 0.96" monochrome OLED
- http://chocoball.tistory.com/entry/Hardware-SSD1306-128x64-monochrome-OLED
* SSD1331 96x64 0.95" full color OLED
- http://chocoball.tistory.com/entry/Hardware-SSD1331-96x64-full-color-OLED
추가로 지금 만들고 있는, "Safecast bGeigie Nano" 의 구성품을 보니, 마침 "Adafruit SSD1306 128x64 1.3inch" 가 달려있네요?!
* Hardware | Safecast bGeigie Nano 를 조립해 보자 - 1
- http://chocoball.tistory.com/entry/Hardware-Safecast-bGeigie-Nano-1
이왕 OLED 를 가지고 놀기 시작한거, 끝가지 해보자 하고 구동시켜 봅니다.
조립 전에 제품이 정상작동 하는지도 보고싶구요.
Adafruit 는 거의 레퍼런스급 제품이고, AliExpress 을 통한 짝퉁 중국산이 아닌 제품으로 구동시켜 보는 것은 거의 처음인것 같습니다.
2. 외형
1.3" 다 보니, 지금까지의 0.95" / 0.96" 보다 확실히 큰 것을 느낄 수 있습니다.
뒷면입니다.
프린팅 된것도 선명하고, I2C로 사용시에는 SJ1 / SJ2 를 쇼트시키라고 표현도 되어 있습니다.
"5V READY" 라고 하네요. 자체 레귤레이터가 달려 있습니다.
단, 저는 기기에 무리를 주기 싫기 때문에 무조건 "3.3V" 로 구동시켜 보겠습니다.
그간 테스트 했던 OLED 와의 비교샷 입니다.
화면도 클 뿐만 아니라, pin 갯수도 많습니다.
SPI 대응도 되고 I2C 대응도 모두 될 수 있게 만들어져 있기 때문인것 같아요.
3.Layout
Pin 배열은 아래 link 를 참고하였습니다. (Adafruit 제조사 사이트)
- https://learn.adafruit.com/monochrome-oled-breakouts/wiring-1-dot-3-128x64
Adafruit | Arduino SSD1306 | Nano ---------------------------- Data | D9 Clk | D10 SA0(DC) | D11 Rst | D13 CS | D12 3v3 | Vin | 3.3V GND | GND ----------------------------
실제 배선 모양입니다.
4.Sketch
소스는 Arduino IDE 에서,
아래처럼 "File > Examples > Adafruit SDD1306 > ssd1306_128x64_spi" 를 선택하면 됩니다.
원본 소스는 다음과 같습니다.
5. 구동
실제 구동한 동영상 입니다.
소스 코드와 제품 자체가 모두 Adafruit 가 만든 것이니 당연 잘 됩니다.
거기에 Arduino 진영과 Adafruit 가 협력하여 만든 Arduino Micro 까지 구비하여 구동해 봤습니다. (완전체)
당연 잘 돌아 갑니다.
이제 3형제 다 모여서 구동시켜 봅니다.
확실히 Adafruit 제품의 구동 속도가 제일 빠릅니다.
소스 및 pin 배열을 Hardware SPI 로 변경하고 동작시키면 더 빠르겠지요?
FIN
이제 OLED는 거의 다 사용해 본것 같네.
'Hardware' 카테고리의 다른 글
Hardware | SSD1306 monochrome OLED 를 가지고 VU meter 를 만들어보자 (0) | 2017.09.19 |
---|---|
Hardware | TSSR 3.5mm audio jack 구매하기 (0) | 2017.09.19 |
Hardware | SSD1306 128x64 monochrome OLED 를 사용해보자 (0) | 2017.09.14 |
Hardware | SSD1331 96x64 full color OLED 를 사용해보자 (0) | 2017.09.07 |
Hardware | FTDI Serial Adapter 를 사용해 보자 (0) | 2017.09.05 |
1. 상태 표시
Arduino 를 하다 보면, 표시창을 이용하여 상태를 알고 싶어 집니다.
PC로 말할것 같으면 모니터 같은 것이죠.
반짝반짝 빛나는 LED 도 좋지만, 쿨한 작은 모니터도 좋습니다.
AliExpress 에서 뒤져본 결과, 이런 적은 display 가 있네요!
2. 주문
AliExpress 는 무료 배송이 감사합니다.
3. 도착
재미 있는 것은, 전원 pin 이름이 보통 "VCC" 인데, "VDD" 로 써져 있으며, "SCL" 을 "SCK" 로 써 있는 부분입니다.
아루래도 라이센스 부분을 피해가기 위해서 그런게 아닐까 합니다만, 사용하는데 지장은 없습니다.
드라이버 칩은 뒤에 가려져서 보이지 않는것 같습니다.
Full color OLED 와의 비교샷 입니다.
Full color OLED 의 자세한 이야기는 아래 link 를 참고해 주세요.
- http://chocoball.tistory.com/entry/Hardware-SSD1331-96x64-full-color-OLED
SSD1306 의 datasheet 입니다.
세로는 확실히 monochrome 이 짧은게 보입니다만, 가로는 같아 보입니다.
확실히 full color OLED 의 보드가 복잡합니다.
4. Layout
빵판에서 Arduino 와 연결은 다음과 같이 하면 됩니다.
SSD1306 | Arduino Nano ---------------------------- GND | GND VDD | 3.3V SCK | A5 SDA | A4 ----------------------------
아래는 실제 회로 구성입니다.
5. I2C vs. SPI
항상 궁금했던 것은 arduino 와의 interface 에서 I2C 와 SPI 의 차이가 궁금했습니다.
특히 OLED 디바이스는 이 두가지로 극명하게 갈립니다.
SPI 는 비싼 편이고, pin 수가 많습니다.
바로 느낌이 SPI 아 좋아 보이죠? 속도면에서는 그렇습니다.
다만, 동시에 연결은 I2C 가 좋다고 하네요.
아래 link 들에서 참고하였습니다.
- http://luma-oled.readthedocs.io/en/latest/hardware.html
- https://www.youtube.com/watch?v=vECfvdBLHI0
6. I2C detect
본 OLED device 가 어떤 I2C 어드레스를 갖는지 궁금할 땐, "i2cdetect" 라는 sketch 를 사용하여 확인 가능합니다.
#include "Wire.h" #include "i2cdetect.h" void setup() { Wire.begin(); Serial.begin(9600); Serial.println("i2cdetect example\n"); Serial.print("Scanning address range 0x03-0x77\n\n"); } void loop() { i2cdetect(); // default range from 0x03 to 0x77 delay(2000); }
결과는 "0x3c" 가 나옵니다.
향후, sketch 의 소스를 보고 해당 값들이 잘 들어갔는지 확인할 수 있습니다.
7. Adafruit Sketch
OLED 의 동작을 확인할 수 있는 sample sketch 는 여러개가 있습니다.
유명한 것은 Adafruit 와 U8g 입니다.
우선 Adafruit 를 이용해 봅니다.
아래 link 에서 library 등을 다운로드 받아 arduino 폴더에 설치합니다.
- https://learn.adafruit.com/monochrome-oled-breakouts/arduino-library-and-examples
참고로 제품이 128x64 이므로, "ssd1306_128x64_i2c" 를 선택하면 동작하지 않습니다.
i2c 의 다른 셈플인 "ssd1306_128x32_i2c" 를 선택해야지만 정상으로 동작합니다.
제품 사이즈도 128x64 가 아니라 128x32 가 아닌가라는 생각도 해 봅니다.
Sketch source 는 다음과 같습니다.
아래는 동작 동영상 입니다.
화려한 내용을 보여줍니다. OLED 를 사용한다는 것이 실감납니다.
8. U8g Sketch
그 다음으로 유명한 U8g library 를 사용해 봅니다.
아래 link 를 참고하였습니다.
- https://github.com/olikraus/u8glib/
주의할 점은, 범용 library 로 작성되어 있어서,
테스트할 device 의 정확한 방식을 정해줘야 합니다.
아래 스샷처럼 정확하게 선택해 줍니다.
다른 I2C 도 있지만, Fast I2C 를 선택하면 가장 빠른 퍼포먼스를 보여줍니다.
Sketch source 는 다음과 같습니다.
/* GraphicsTest.pde >>> Before compiling: Please remove comment from the constructor of the >>> connected graphics display (see below). Universal 8bit Graphics Library, https://github.com/olikraus/u8glib/ Copyright (c) 2012, olikraus@gmail.com All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "U8glib.h" // setup u8g object, please remove comment from one of the following constructor calls // IMPORTANT NOTE: The following list is incomplete. The complete list of supported // devices with all constructor calls is here: https://github.com/olikraus/u8glib/wiki/device //U8GLIB_NHD27OLED_BW u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_NHD27OLED_2X_BW u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_NHD27OLED_GR u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_NHD27OLED_2X_GR u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_NHD31OLED_BW u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_NHD31OLED_2X_BW u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_NHD31OLED_GR u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_NHD31OLED_2X_GR u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_DOGS102 u8g(13, 11, 10, 9, 8); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_DOGM132 u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_DOGM128 u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_DOGM128_2X u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_ST7920_128X64_1X u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 17, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, di=17,rw=16 //U8GLIB_ST7920_128X64_4X u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 17, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, di=17,rw=16 //U8GLIB_ST7920_128X64_1X u8g(18, 16, 17); // SPI Com: SCK = en = 18, MOSI = rw = 16, CS = di = 17 //U8GLIB_ST7920_128X64_4X u8g(18, 16, 17); // SPI Com: SCK = en = 18, MOSI = rw = 16, CS = di = 17 //U8GLIB_ST7920_192X32_1X u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 17, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, di=17,rw=16 //U8GLIB_ST7920_192X32_4X u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 17, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, di=17,rw=16 //U8GLIB_ST7920_192X32_1X u8g(18, 16, 17); // SPI Com: SCK = en = 18, MOSI = rw = 16, CS = di = 17 //U8GLIB_ST7920_192X32_4X u8g(18, 16, 17); // SPI Com: SCK = en = 18, MOSI = rw = 16, CS = di = 17 //U8GLIB_ST7920_192X32_1X u8g(13, 11, 10); // SPI Com: SCK = en = 13, MOSI = rw = 11, CS = di = 10 //U8GLIB_ST7920_192X32_4X u8g(10); // SPI Com: SCK = en = 13, MOSI = rw = 11, CS = di = 10, HW SPI //U8GLIB_ST7920_202X32_1X u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 17, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, di=17,rw=16 //U8GLIB_ST7920_202X32_4X u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 17, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, di=17,rw=16 //U8GLIB_ST7920_202X32_1X u8g(18, 16, 17); // SPI Com: SCK = en = 18, MOSI = rw = 16, CS = di = 17 //U8GLIB_ST7920_202X32_4X u8g(18, 16, 17); // SPI Com: SCK = en = 18, MOSI = rw = 16, CS = di = 17 //U8GLIB_LM6059 u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_LM6063 u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_DOGXL160_BW u8g(10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_DOGXL160_GR u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_DOGXL160_2X_BW u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_DOGXL160_2X_GR u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_PCD8544 u8g(13, 11, 10, 9, 8); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, Reset = 8 //U8GLIB_PCF8812 u8g(13, 11, 10, 9, 8); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, Reset = 8 //U8GLIB_KS0108_128 u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 14, 15, 17, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, cs1=14, cs2=15,di=17,rw=16 //U8GLIB_LC7981_160X80 u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 14, 15, 17, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, cs=14 ,di=15,rw=17, reset = 16 //U8GLIB_LC7981_240X64 u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 14, 15, 17, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, cs=14 ,di=15,rw=17, reset = 16 //U8GLIB_LC7981_240X128 u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 14, 15, 17, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, cs=14 ,di=15,rw=17, reset = 16 //U8GLIB_ILI9325D_320x240 u8g(18,17,19,U8G_PIN_NONE,16 ); // 8Bit Com: D0..D7: 0,1,2,3,4,5,6,7 en=wr=18, cs=17, rs=19, rd=U8G_PIN_NONE, reset = 16 //U8GLIB_SBN1661_122X32 u8g(8,9,10,11,4,5,6,7,14,15, 17, U8G_PIN_NONE, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 cs1=14, cs2=15,di=17,rw=16,reset = 16 //U8GLIB_SSD1306_128X64 u8g(13, 11, 10, 9); // SW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_SSD1306_128X64 u8g(4, 5, 6, 7); // SW SPI Com: SCK = 4, MOSI = 5, CS = 6, A0 = 7 (new white HalTec OLED) //U8GLIB_SSD1306_128X64 u8g(10, 9); // HW SPI Com: CS = 10, A0 = 9 (Hardware Pins are SCK = 13 and MOSI = 11) //U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0); // I2C / TWI U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_DEV_0|U8G_I2C_OPT_NO_ACK|U8G_I2C_OPT_FAST); // Fast I2C / TWI //U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NO_ACK); // Display which does not send AC //U8GLIB_SSD1306_ADAFRUIT_128X64 u8g(13, 11, 10, 9); // SW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_SSD1306_ADAFRUIT_128X64 u8g(10, 9); // HW SPI Com: CS = 10, A0 = 9 (Hardware Pins are SCK = 13 and MOSI = 11) //U8GLIB_SSD1306_128X32 u8g(13, 11, 10, 9); // SW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_SSD1306_128X32 u8g(10, 9); // HW SPI Com: CS = 10, A0 = 9 (Hardware Pins are SCK = 13 and MOSI = 11) //U8GLIB_SSD1306_128X32 u8g(U8G_I2C_OPT_NONE); // I2C / TWI //U8GLIB_SSD1306_64X48 u8g(13, 11, 10, 9); // SW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_SSD1306_64X48 u8g(10, 9); // HW SPI Com: CS = 10, A0 = 9 (Hardware Pins are SCK = 13 and MOSI = 11) //U8GLIB_SSD1306_64X48 u8g(U8G_I2C_OPT_NONE); // I2C / TWI //U8GLIB_SH1106_128X64 u8g(13, 11, 10, 9); // SW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_SH1106_128X64 u8g(4, 5, 6, 7); // SW SPI Com: SCK = 4, MOSI = 5, CS = 6, A0 = 7 (new blue HalTec OLED) //U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NONE); // I2C / TWI //U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_DEV_0|U8G_I2C_OPT_FAST); // Dev 0, Fast I2C / TWI //U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NO_ACK); // Display which does not send ACK //U8GLIB_SSD1309_128X64 u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_SSD1327_96X96_GR u8g(U8G_I2C_OPT_NONE); // I2C //U8GLIB_SSD1327_96X96_2X_GR u8g(U8G_I2C_OPT_NONE); // I2C //U8GLIB_UC1611_DOGM240 u8g(U8G_I2C_OPT_NONE); // I2C //U8GLIB_UC1611_DOGM240 u8g(13, 11, 10, 9); // SW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_UC1611_DOGM240 u8g(10, 9); // HW SPI Com: CS = 10, A0 = 9 (Hardware Pins are SCK = 13 and MOSI = 11) //U8GLIB_UC1611_DOGM240 u8g(10, 9); // HW SPI Com: CS = 10, A0 = 9 (Hardware Pins are SCK = 13 and MOSI = 11) //U8GLIB_UC1611_DOGM240 u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 3, 17, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, cs=3, di/a0=17,rw=16 //U8GLIB_UC1611_DOGXL240 u8g(U8G_I2C_OPT_NONE); // I2C //U8GLIB_UC1611_DOGXL240 u8g(13, 11, 10, 9); // SW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_UC1611_DOGXL240 u8g(10, 9); // HW SPI Com: CS = 10, A0 = 9 (Hardware Pins are SCK = 13 and MOSI = 11) //U8GLIB_UC1611_DOGXL240 u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 3, 17, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, cs=3, di/a0=17,rw=16 //U8GLIB_NHD_C12864 u8g(13, 11, 10, 9, 8); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, RST = 8 //U8GLIB_NHD_C12832 u8g(13, 11, 10, 9, 8); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, RST = 8 //U8GLIB_LD7032_60x32 u8g(13, 11, 10, 9, 8); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, RST = 8 //U8GLIB_LD7032_60x32 u8g(11, 12, 9, 10, 8); // SPI Com: SCK = 11, MOSI = 12, CS = 9, A0 = 10, RST = 8 (SW SPI Nano Board) //U8GLIB_UC1608_240X64 u8g(13, 11, 10, 9, 8); // SW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, RST = 8 //U8GLIB_UC1608_240X64_2X u8g(13, 11, 10, 9, 8); // SW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, RST = 8 //U8GLIB_UC1608_240X64 u8g(10, 9, 8); // HW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, RST = 8 //U8GLIB_UC1608_240X64_2X u8g(10, 9, 8); // HW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, RST = 8 //U8GLIB_UC1608_240X u8g(13, 11, 10, 9, 8); // SW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, RST = 8 //U8GLIB_UC1608_240X64_2X u8g(13, 11, 10, 9, 8); // SW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, RST = 8 //U8GLIB_UC1608_240X64 u8g(10, 9, 8); // HW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, RST = 8 //U8GLIB_UC1608_240X64_2X u8g(10, 9, 8); // HW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, RST = 8 //U8GLIB_T6963_240X128 u8g(8, 9, 10, 11, 4, 5, 6, 7, 14, 15, 17, 18, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7, cs=14, a0=15, wr=17, rd=18, reset=16 //U8GLIB_T6963_128X128 u8g(8, 9, 10, 11, 4, 5, 6, 7, 14, 15, 17, 18, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7, cs=14, a0=15, wr=17, rd=18, reset=16 //U8GLIB_T6963_240X64 u8g(8, 9, 10, 11, 4, 5, 6, 7, 14, 15, 17, 18, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7, cs=14, a0=15, wr=17, rd=18, reset=16 //U8GLIB_T6963_128X64 u8g(8, 9, 10, 11, 4, 5, 6, 7, 14, 15, 17, 18, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7, cs=14, a0=15, wr=17, rd=18, reset=16 //U8GLIB_HT1632_24X16 u8g(3, 2, 4); // WR = 3, DATA = 2, CS = 4 //U8GLIB_SSD1351_128X128_332 u8g(13, 11, 8, 9, 7); // Arduino UNO: SW SPI Com: SCK = 13, MOSI = 11, CS = 8, A0 = 9, RESET = 7 (http://electronics.ilsoft.co.uk/ArduinoShield.aspx) //U8GLIB_SSD1351_128X128_332 u8g(76, 75, 8, 9, 7); // Arduino DUE: SW SPI Com: SCK = 13, MOSI = 11, CS = 8, A0 = 9, RESET = 7 (http://electronics.ilsoft.co.uk/ArduinoShield.aspx) //U8GLIB_SSD1351_128X128_332 u8g(8, 9, 7); // Arduino: HW SPI Com: SCK = 13, MOSI = 11, CS = 8, A0 = 9, RESET = 7 (http://electronics.ilsoft.co.uk/ArduinoShield.aspx) //U8GLIB_SSD1351_128X128_HICOLOR u8g(76, 75, 8, 9, 7); // Arduino DUE, SW SPI Com: SCK = 76, MOSI = 75, CS = 8, A0 = 9, RESET = 7 (http://electronics.ilsoft.co.uk/ArduinoShield.aspx) //U8GLIB_SSD1351_128X128_HICOLOR u8g(8, 9, 7); // Arduino, HW SPI Com: SCK = 76, MOSI = 75, CS = 8, A0 = 9, RESET = 7 (http://electronics.ilsoft.co.uk/ArduinoShield.aspx) //U8GLIB_SSD1351_128X128GH_332 u8g(8, 9, 7); // Arduino, HW SPI Com: SCK = 76, MOSI = 75, CS = 8, A0 = 9, RESET = 7 (Freetronics OLED) //U8GLIB_SSD1351_128X128GH_HICOLOR u8g(8, 9, 7); // Arduino, HW SPI Com: SCK = 76, MOSI = 75, CS = 8, A0 = 9, RESET = 7 (Freetronics OLED) void u8g_prepare(void) { u8g.setFont(u8g_font_6x10); u8g.setFontRefHeightExtendedText(); u8g.setDefaultForegroundColor(); u8g.setFontPosTop(); } void u8g_box_frame(uint8_t a) { u8g.drawStr( 0, 0, "drawBox"); u8g.drawBox(5,10,20,10); u8g.drawBox(10+a,15,30,7); u8g.drawStr( 0, 30, "drawFrame"); u8g.drawFrame(5,10+30,20,10); u8g.drawFrame(10+a,15+30,30,7); } void u8g_disc_circle(uint8_t a) { u8g.drawStr( 0, 0, "drawDisc"); u8g.drawDisc(10,18,9); u8g.drawDisc(24+a,16,7); u8g.drawStr( 0, 30, "drawCircle"); u8g.drawCircle(10,18+30,9); u8g.drawCircle(24+a,16+30,7); } void u8g_r_frame(uint8_t a) { u8g.drawStr( 0, 0, "drawRFrame/Box"); u8g.drawRFrame(5, 10,40,30, a+1); u8g.drawRBox(50, 10,25,40, a+1); } void u8g_string(uint8_t a) { u8g.drawStr(30+a,31, " 0"); u8g.drawStr90(30,31+a, " 90"); u8g.drawStr180(30-a,31, " 180"); u8g.drawStr270(30,31-a, " 270"); } void u8g_line(uint8_t a) { u8g.drawStr( 0, 0, "drawLine"); u8g.drawLine(7+a, 10, 40, 55); u8g.drawLine(7+a*2, 10, 60, 55); u8g.drawLine(7+a*3, 10, 80, 55); u8g.drawLine(7+a*4, 10, 100, 55); } void u8g_triangle(uint8_t a) { uint16_t offset = a; u8g.drawStr( 0, 0, "drawTriangle"); u8g.drawTriangle(14,7, 45,30, 10,40); u8g.drawTriangle(14+offset,7-offset, 45+offset,30-offset, 57+offset,10-offset); u8g.drawTriangle(57+offset*2,10, 45+offset*2,30, 86+offset*2,53); u8g.drawTriangle(10+offset,40+offset, 45+offset,30+offset, 86+offset,53+offset); } void u8g_ascii_1() { char s[2] = " "; uint8_t x, y; u8g.drawStr( 0, 0, "ASCII page 1"); for( y = 0; y < 6; y++ ) { for( x = 0; x < 16; x++ ) { s[0] = y*16 + x + 32; u8g.drawStr(x*7, y*10+10, s); } } } void u8g_ascii_2() { char s[2] = " "; uint8_t x, y; u8g.drawStr( 0, 0, "ASCII page 2"); for( y = 0; y < 6; y++ ) { for( x = 0; x < 16; x++ ) { s[0] = y*16 + x + 160; u8g.drawStr(x*7, y*10+10, s); } } } void u8g_extra_page(uint8_t a) { if ( u8g.getMode() == U8G_MODE_HICOLOR || u8g.getMode() == U8G_MODE_R3G3B2) { /* draw background (area is 128x128) */ u8g_uint_t r, g, b; b = a << 5; for( g = 0; g < 64; g++ ) { for( r = 0; r < 64; r++ ) { u8g.setRGB(r<<2, g<<2, b ); u8g.drawPixel(g, r); } } u8g.setRGB(255,255,255); u8g.drawStr( 66, 0, "Color Page"); } else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) { u8g.drawStr( 66, 0, "Gray Level"); u8g.setColorIndex(1); u8g.drawBox(0, 4, 64, 32); u8g.drawBox(70, 20, 4, 12); u8g.setColorIndex(2); u8g.drawBox(0+1*a, 4+1*a, 64-2*a, 32-2*a); u8g.drawBox(74, 20, 4, 12); u8g.setColorIndex(3); u8g.drawBox(0+2*a, 4+2*a, 64-4*a, 32-4*a); u8g.drawBox(78, 20, 4, 12); } else { u8g.drawStr( 0, 12, "setScale2x2"); u8g.setScale2x2(); u8g.drawStr( 0, 6+a, "setScale2x2"); u8g.undoScale(); } } uint8_t draw_state = 0; void draw(void) { u8g_prepare(); switch(draw_state >> 3) { case 0: u8g_box_frame(draw_state&7); break; case 1: u8g_disc_circle(draw_state&7); break; case 2: u8g_r_frame(draw_state&7); break; case 3: u8g_string(draw_state&7); break; case 4: u8g_line(draw_state&7); break; case 5: u8g_triangle(draw_state&7); break; case 6: u8g_ascii_1(); break; case 7: u8g_ascii_2(); break; case 8: u8g_extra_page(draw_state&7); break; } } void setup(void) { // flip screen, if required //u8g.setRot180(); #if defined(ARDUINO) pinMode(13, OUTPUT); digitalWrite(13, HIGH); #endif } void loop(void) { // picture loop u8g.firstPage(); do { draw(); } while( u8g.nextPage() ); // increase the state draw_state++; if ( draw_state >= 9*8 ) draw_state = 0; // rebuild the picture after some delay //delay(150); }
가장 빠르지만, 아래처럼 arduino 의 빨간 led 가 미친듯이 점멸합니다.
아마 process 를 많이 사용하는 듯 합니다.
U8g library 에 "Rotation" 셈플도 있어서 확인해 봤습니다.
글씨도 세로로 바로 회전할 수 있는게 신기합니다.
Sketch 는 다음과 같습니다.
/* Rotation.pde Example code for RotXXX functions. >>> Before compiling: Please remove comment from the constructor of the >>> connected graphics display (see below). Universal 8bit Graphics Library, https://github.com/olikraus/u8glib/ Copyright (c) 2012, olikraus@gmail.com All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "U8glib.h" // setup u8g object, please remove comment from one of the following constructor calls // IMPORTANT NOTE: The following list is incomplete. The complete list of supported // devices with all constructor calls is here: https://github.com/olikraus/u8glib/wiki/device //U8GLIB_NHD27OLED_BW u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_NHD27OLED_2X_BW u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_NHD27OLED_GR u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_NHD27OLED_2X_GR u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_NHD31OLED_BW u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_NHD31OLED_2X_BW u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_NHD31OLED_GR u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_NHD31OLED_2X_GR u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_DOGS102 u8g(13, 11, 10, 9, 8); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_DOGM132 u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_DOGM128 u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_DOGM128_2X u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_ST7920_128X64_1X u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 17, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, di=17,rw=16 //U8GLIB_ST7920_128X64_4X u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 17, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, di=17,rw=16 //U8GLIB_ST7920_128X64_1X u8g(18, 16, 17); // SPI Com: SCK = en = 18, MOSI = rw = 16, CS = di = 17 //U8GLIB_ST7920_128X64_4X u8g(18, 16, 17); // SPI Com: SCK = en = 18, MOSI = rw = 16, CS = di = 17 //U8GLIB_ST7920_192X32_1X u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 17, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, di=17,rw=16 //U8GLIB_ST7920_192X32_4X u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 17, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, di=17,rw=16 //U8GLIB_ST7920_192X32_1X u8g(18, 16, 17); // SPI Com: SCK = en = 18, MOSI = rw = 16, CS = di = 17 //U8GLIB_ST7920_192X32_4X u8g(18, 16, 17); // SPI Com: SCK = en = 18, MOSI = rw = 16, CS = di = 17 //U8GLIB_ST7920_192X32_1X u8g(13, 11, 10); // SPI Com: SCK = en = 13, MOSI = rw = 11, CS = di = 10 //U8GLIB_ST7920_192X32_4X u8g(10); // SPI Com: SCK = en = 13, MOSI = rw = 11, CS = di = 10, HW SPI //U8GLIB_ST7920_202X32_1X u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 17, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, di=17,rw=16 //U8GLIB_ST7920_202X32_4X u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 17, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, di=17,rw=16 //U8GLIB_ST7920_202X32_1X u8g(18, 16, 17); // SPI Com: SCK = en = 18, MOSI = rw = 16, CS = di = 17 //U8GLIB_ST7920_202X32_4X u8g(18, 16, 17); // SPI Com: SCK = en = 18, MOSI = rw = 16, CS = di = 17 //U8GLIB_LM6059 u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_LM6063 u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_DOGXL160_BW u8g(10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_DOGXL160_GR u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_DOGXL160_2X_BW u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_DOGXL160_2X_GR u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_PCD8544 u8g(13, 11, 10, 9, 8); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, Reset = 8 //U8GLIB_PCF8812 u8g(13, 11, 10, 9, 8); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, Reset = 8 //U8GLIB_KS0108_128 u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 14, 15, 17, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, cs1=14, cs2=15,di=17,rw=16 //U8GLIB_LC7981_160X80 u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 14, 15, 17, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, cs=14 ,di=15,rw=17, reset = 16 //U8GLIB_LC7981_240X64 u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 14, 15, 17, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, cs=14 ,di=15,rw=17, reset = 16 //U8GLIB_LC7981_240X128 u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 14, 15, 17, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, cs=14 ,di=15,rw=17, reset = 16 //U8GLIB_ILI9325D_320x240 u8g(18,17,19,U8G_PIN_NONE,16 ); // 8Bit Com: D0..D7: 0,1,2,3,4,5,6,7 en=wr=18, cs=17, rs=19, rd=U8G_PIN_NONE, reset = 16 //U8GLIB_SBN1661_122X32 u8g(8,9,10,11,4,5,6,7,14,15, 17, U8G_PIN_NONE, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 cs1=14, cs2=15,di=17,rw=16,reset = 16 //U8GLIB_SSD1306_128X64 u8g(13, 11, 10, 9); // SW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_SSD1306_128X64 u8g(4, 5, 6, 7); // SW SPI Com: SCK = 4, MOSI = 5, CS = 6, A0 = 7 (new white HalTec OLED) //U8GLIB_SSD1306_128X64 u8g(10, 9); // HW SPI Com: CS = 10, A0 = 9 (Hardware Pins are SCK = 13 and MOSI = 11) //U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0); // I2C / TWI U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_DEV_0|U8G_I2C_OPT_NO_ACK|U8G_I2C_OPT_FAST); // Fast I2C / TWI //U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NO_ACK); // Display which does not send AC //U8GLIB_SSD1306_ADAFRUIT_128X64 u8g(13, 11, 10, 9); // SW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_SSD1306_ADAFRUIT_128X64 u8g(10, 9); // HW SPI Com: CS = 10, A0 = 9 (Hardware Pins are SCK = 13 and MOSI = 11) //U8GLIB_SSD1306_128X32 u8g(13, 11, 10, 9); // SW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_SSD1306_128X32 u8g(10, 9); // HW SPI Com: CS = 10, A0 = 9 (Hardware Pins are SCK = 13 and MOSI = 11) //U8GLIB_SSD1306_128X32 u8g(U8G_I2C_OPT_NONE); // I2C / TWI //U8GLIB_SSD1306_64X48 u8g(13, 11, 10, 9); // SW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_SSD1306_64X48 u8g(10, 9); // HW SPI Com: CS = 10, A0 = 9 (Hardware Pins are SCK = 13 and MOSI = 11) //U8GLIB_SSD1306_64X48 u8g(U8G_I2C_OPT_NONE); // I2C / TWI //U8GLIB_SH1106_128X64 u8g(13, 11, 10, 9); // SW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_SH1106_128X64 u8g(4, 5, 6, 7); // SW SPI Com: SCK = 4, MOSI = 5, CS = 6, A0 = 7 (new blue HalTec OLED) //U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NONE); // I2C / TWI //U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_DEV_0|U8G_I2C_OPT_FAST); // Dev 0, Fast I2C / TWI //U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NO_ACK); // Display which does not send ACK //U8GLIB_SSD1309_128X64 u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_SSD1327_96X96_GR u8g(U8G_I2C_OPT_NONE); // I2C //U8GLIB_SSD1327_96X96_2X_GR u8g(U8G_I2C_OPT_NONE); // I2C //U8GLIB_UC1611_DOGM240 u8g(U8G_I2C_OPT_NONE); // I2C //U8GLIB_UC1611_DOGM240 u8g(13, 11, 10, 9); // SW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_UC1611_DOGM240 u8g(10, 9); // HW SPI Com: CS = 10, A0 = 9 (Hardware Pins are SCK = 13 and MOSI = 11) //U8GLIB_UC1611_DOGM240 u8g(10, 9); // HW SPI Com: CS = 10, A0 = 9 (Hardware Pins are SCK = 13 and MOSI = 11) //U8GLIB_UC1611_DOGM240 u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 3, 17, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, cs=3, di/a0=17,rw=16 //U8GLIB_UC1611_DOGXL240 u8g(U8G_I2C_OPT_NONE); // I2C //U8GLIB_UC1611_DOGXL240 u8g(13, 11, 10, 9); // SW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 //U8GLIB_UC1611_DOGXL240 u8g(10, 9); // HW SPI Com: CS = 10, A0 = 9 (Hardware Pins are SCK = 13 and MOSI = 11) //U8GLIB_UC1611_DOGXL240 u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 3, 17, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, cs=3, di/a0=17,rw=16 //U8GLIB_NHD_C12864 u8g(13, 11, 10, 9, 8); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, RST = 8 //U8GLIB_NHD_C12832 u8g(13, 11, 10, 9, 8); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, RST = 8 //U8GLIB_LD7032_60x32 u8g(13, 11, 10, 9, 8); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, RST = 8 //U8GLIB_LD7032_60x32 u8g(11, 12, 9, 10, 8); // SPI Com: SCK = 11, MOSI = 12, CS = 9, A0 = 10, RST = 8 (SW SPI Nano Board) //U8GLIB_UC1608_240X64 u8g(13, 11, 10, 9, 8); // SW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, RST = 8 //U8GLIB_UC1608_240X64_2X u8g(13, 11, 10, 9, 8); // SW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, RST = 8 //U8GLIB_UC1608_240X64 u8g(10, 9, 8); // HW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, RST = 8 //U8GLIB_UC1608_240X64_2X u8g(10, 9, 8); // HW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, RST = 8 //U8GLIB_UC1608_240X u8g(13, 11, 10, 9, 8); // SW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, RST = 8 //U8GLIB_UC1608_240X64_2X u8g(13, 11, 10, 9, 8); // SW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, RST = 8 //U8GLIB_UC1608_240X64 u8g(10, 9, 8); // HW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, RST = 8 //U8GLIB_UC1608_240X64_2X u8g(10, 9, 8); // HW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, RST = 8 //U8GLIB_T6963_240X128 u8g(8, 9, 10, 11, 4, 5, 6, 7, 14, 15, 17, 18, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7, cs=14, a0=15, wr=17, rd=18, reset=16 //U8GLIB_T6963_128X128 u8g(8, 9, 10, 11, 4, 5, 6, 7, 14, 15, 17, 18, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7, cs=14, a0=15, wr=17, rd=18, reset=16 //U8GLIB_T6963_240X64 u8g(8, 9, 10, 11, 4, 5, 6, 7, 14, 15, 17, 18, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7, cs=14, a0=15, wr=17, rd=18, reset=16 //U8GLIB_T6963_128X64 u8g(8, 9, 10, 11, 4, 5, 6, 7, 14, 15, 17, 18, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7, cs=14, a0=15, wr=17, rd=18, reset=16 //U8GLIB_HT1632_24X16 u8g(3, 2, 4); // WR = 3, DATA = 2, CS = 4 //U8GLIB_SSD1351_128X128_332 u8g(13, 11, 8, 9, 7); // Arduino UNO: SW SPI Com: SCK = 13, MOSI = 11, CS = 8, A0 = 9, RESET = 7 (http://electronics.ilsoft.co.uk/ArduinoShield.aspx) //U8GLIB_SSD1351_128X128_332 u8g(76, 75, 8, 9, 7); // Arduino DUE: SW SPI Com: SCK = 13, MOSI = 11, CS = 8, A0 = 9, RESET = 7 (http://electronics.ilsoft.co.uk/ArduinoShield.aspx) //U8GLIB_SSD1351_128X128_332 u8g(8, 9, 7); // Arduino: HW SPI Com: SCK = 13, MOSI = 11, CS = 8, A0 = 9, RESET = 7 (http://electronics.ilsoft.co.uk/ArduinoShield.aspx) //U8GLIB_SSD1351_128X128_HICOLOR u8g(76, 75, 8, 9, 7); // Arduino DUE, SW SPI Com: SCK = 76, MOSI = 75, CS = 8, A0 = 9, RESET = 7 (http://electronics.ilsoft.co.uk/ArduinoShield.aspx) //U8GLIB_SSD1351_128X128_HICOLOR u8g(8, 9, 7); // Arduino, HW SPI Com: SCK = 76, MOSI = 75, CS = 8, A0 = 9, RESET = 7 (http://electronics.ilsoft.co.uk/ArduinoShield.aspx) //U8GLIB_SSD1351_128X128GH_332 u8g(8, 9, 7); // Arduino, HW SPI Com: SCK = 76, MOSI = 75, CS = 8, A0 = 9, RESET = 7 (Freetronics OLED) //U8GLIB_SSD1351_128X128GH_HICOLOR u8g(8, 9, 7); // Arduino, HW SPI Com: SCK = 76, MOSI = 75, CS = 8, A0 = 9, RESET = 7 (Freetronics OLED) uint8_t offset = 0; void draw(void) { // graphic commands to redraw the complete screen should be placed here u8g.setFont(u8g_font_unifont); u8g.drawStr( 0+0, 20+0, "Hello!"); u8g.drawStr( 0+2, 20+16, "Hello!"); u8g.drawBox(0, 0, 3, 3); u8g.drawBox(u8g.getWidth()-6, 0, 6, 6); u8g.drawBox(u8g.getWidth()-9, u8g.getHeight()-9, 9, 9); u8g.drawBox(0, u8g.getHeight()-12, 12, 12); } void setup(void) { } void rotate(void) { static uint8_t dir = 0; static unsigned long next_rotation = 0; if ( next_rotation < millis() ) { switch(dir) { case 0: u8g.undoRotation(); break; case 1: u8g.setRot90(); break; case 2: u8g.setRot180(); break; case 3: u8g.setRot270(); offset = ( offset + 1 ) & 0x0f; break; } dir++; dir &= 3; next_rotation = millis(); next_rotation += 1000; } } void loop(void) { // screen rotation rotate(); // picture loop u8g.firstPage(); do { draw(); } while( u8g.nextPage() ); // rebuild the picture after some delay delay(100); }
동작 동영상은 다음과 같습니다.
9. U8g2 Sketch
U8g 를 작성하신 분이, 더이상 U8g를 업그래이드 하지 않고 U8g2 를 개발하셨습니다.
- https://github.com/olikraus/u8g2/
여기서도 마찬가지로,
보유하고 있는 device 를 로딩할 수 있도록 찾고 comment out 해줍니다.
Sketch 는 다음과 같습니다.
/* GraphicsTest.ino Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) Copyright (c) 2016, olikraus@gmail.com All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Arduino.h" #include "U8g2lib.h" #ifdef U8X8_HAVE_HW_SPI #include "SPI.h" #endif #ifdef U8X8_HAVE_HW_I2C #include "Wire.h" #endif /* U8glib Example Overview: Frame Buffer Examples: clearBuffer/sendBuffer. Fast, but may not work with all Arduino boards because of RAM consumption Page Buffer Examples: firstPage/nextPage. Less RAM usage, should work with all Arduino boards. U8x8 Text Only Example: No RAM usage, direct communication with display controller. No graphics, 8x8 Text only. */ // Please UNCOMMENT one of the contructor lines below // U8g2 Contructor List (Frame Buffer) // The complete list is available here: https://github.com/olikraus/u8g2/wiki/u8g2setupcpp // Please update the pin numbers according to your setup. Use U8X8_PIN_NONE if the reset pin is not connected //U8G2_SSD1306_128X64_NONAME_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); //U8G2_SSD1306_128X64_NONAME_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 12, /* dc=*/ 4, /* reset=*/ 6); // Arduboy (Production, Kickstarter Edition) //U8G2_SSD1306_128X64_NONAME_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); //U8G2_SSD1306_128X64_NONAME_F_3W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* reset=*/ 8); U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); //U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* reset=*/ 8); //U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE); // All Boards without Reset of the Display //U8G2_SSD1306_128X64_NONAME_F_6800 u8g2(U8G2_R0, 13, 11, 2, 3, 4, 5, 6, A4, /*enable=*/ 7, /*cs=*/ 10, /*dc=*/ 9, /*reset=*/ 8); //U8G2_SSD1306_128X64_NONAME_F_8080 u8g2(U8G2_R0, 13, 11, 2, 3, 4, 5, 6, A4, /*enable=*/ 7, /*cs=*/ 10, /*dc=*/ 9, /*reset=*/ 8); //U8G2_SSD1306_128X64_VCOMH0_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // same as the NONAME variant, but maximizes setContrast() range //U8G2_SH1106_128X64_NONAME_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); //U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); //U8G2_SH1106_128X64_VCOMH0_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // same as the NONAME variant, but maximizes setContrast() range //U8G2_SSD1306_128X32_UNIVISION_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ 21, /* data=*/ 20, /* reset=*/ U8X8_PIN_NONE); // Adafruit Feather M0 Basic Proto + FeatherWing OLED //U8G2_SSD1306_128X32_UNIVISION_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE); // Adafruit Feather ESP8266/32u4 Boards + FeatherWing OLED //U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); // Adafruit ESP8266/32u4/ARM Boards + FeatherWing OLED //U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ SCL, /* data=*/ SDA); // pin remapping with ESP8266 HW I2C //U8G2_SSD1306_64X48_ER_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); // EastRising 0.66" OLED breakout board, Uno: A4=SDA, A5=SCL, 5V powered //U8G2_SSD1306_64X32_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); //U8G2_SSD1306_96X16_ER_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); // EastRising 0.69" OLED //U8G2_SSD1322_NHD_256X64_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Enable U8G2_16BIT in u8g2.h //U8G2_SSD1322_NHD_256X64_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Enable U8G2_16BIT in u8g2.h //U8G2_SSD1325_NHD_128X64_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); //U8G2_SSD1325_NHD_128X64_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); //U8G2_SSD1327_SEEED_96X96_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE); // Seeedstudio Grove OLED 96x96 //U8G2_SSD1327_SEEED_96X96_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); // Seeedstudio Grove OLED 96x96 //U8G2_SSD1329_128X96_NONAME_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); //U8G2_SSD1329_128X96_NONAME_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); //U8G2_SSD1305_128X32_NONAME_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); //U8G2_SSD1305_128X32_NONAME_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); //U8G2_SSD1309_128X64_NONAME0_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); //U8G2_SSD1309_128X64_NONAME0_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); //U8G2_SSD1309_128X64_NONAME2_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); //U8G2_SSD1309_128X64_NONAME2_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); //U8G2_LD7032_60X32_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 11, /* data=*/ 12, /* cs=*/ 9, /* dc=*/ 10, /* reset=*/ 8); // SW SPI Nano Board //U8G2_LD7032_60X32_F_4W_SW_I2C u8g2(U8G2_R0, /* clock=*/ 11, /* data=*/ 12, /* reset=*/ U8X8_PIN_NONE); // NOT TESTED! //U8G2_UC1701_EA_DOGS102_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); //U8G2_UC1701_EA_DOGS102_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); //U8G2_PCD8544_84X48_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Nokia 5110 Display //U8G2_PCD8544_84X48_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Nokia 5110 Display //U8G2_PCF8812_96X65_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Could be also PCF8814 //U8G2_PCF8812_96X65_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Could be also PCF8814 //U8G2_KS0108_128X64_F u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 18, /*dc=*/ 17, /*cs0=*/ 14, /*cs1=*/ 15, /*cs2=*/ U8X8_PIN_NONE, /* reset=*/ U8X8_PIN_NONE); // Set R/W to low! //U8G2_KS0108_ERM19264_F u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 18, /*dc=*/ 17, /*cs0=*/ 14, /*cs1=*/ 15, /*cs2=*/ 16, /* reset=*/ U8X8_PIN_NONE); // Set R/W to low! //U8G2_ST7920_192X32_F_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 18, /*cs=*/ U8X8_PIN_NONE, /*dc=*/ 17, /*reset=*/ U8X8_PIN_NONE); //U8G2_ST7920_192X32_F_SW_SPI u8g2(U8G2_R0, /* clock=*/ 18 /* A4 */ , /* data=*/ 16 /* A2 */, /* CS=*/ 17 /* A3 */, /* reset=*/ U8X8_PIN_NONE); //U8G2_ST7920_128X64_F_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 18 /* A4 */, /*cs=*/ U8X8_PIN_NONE, /*dc/rs=*/ 17 /* A3 */, /*reset=*/ 15 /* A1 */); // Remember to set R/W to 0 //U8G2_ST7920_128X64_F_SW_SPI u8g2(U8G2_R0, /* clock=*/ 18 /* A4 */ , /* data=*/ 16 /* A2 */, /* CS=*/ 17 /* A3 */, /* reset=*/ U8X8_PIN_NONE); //U8G2_ST7920_128X64_F_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* CS=*/ 10, /* reset=*/ 8); //U8G2_ST7920_128X64_F_HW_SPI u8g2(U8G2_R0, /* CS=*/ 10, /* reset=*/ 8); //U8G2_ST7565_EA_DOGM128_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); //U8G2_ST7565_EA_DOGM128_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); //U8G2_ST7565_64128N_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); //U8G2_ST7565_64128N_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); //U8G2_ST7565_EA_DOGM132_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ U8X8_PIN_NONE); // DOGM132 Shield //U8G2_ST7565_EA_DOGM132_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ U8X8_PIN_NONE); // DOGM132 Shield //U8G2_ST7565_ZOLEN_128X64_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); //U8G2_ST7565_ZOLEN_128X64_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); //U8G2_ST7565_LM6059_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Adafruit ST7565 GLCD //U8G2_ST7565_LM6059_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Adafruit ST7565 GLCD //U8G2_ST7565_ERC12864_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); //U8G2_ST7565_ERC12864_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); //U8G2_ST7565_NHD_C12832_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); //U8G2_ST7565_NHD_C12832_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); //U8G2_ST7565_NHD_C12864_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); //U8G2_ST7565_NHD_C12864_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); //U8G2_ST7567_PI_132X64_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 7, /* dc=*/ 9, /* reset=*/ 8); // Pax Instruments Shield, LCD_BL=6 //U8G2_ST7567_PI_132X64_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 7, /* dc=*/ 9, /* reset=*/ 8); // Pax Instruments Shield, LCD_BL=6 //U8G2_NT7534_TG12864R_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); //U8G2_NT7534_TG12864R_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); //U8G2_ST7588_JLX12864_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ 5); //U8G2_ST7588_JLX12864_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ 5); //U8G2_IST3020_ERC19264_F_6800 u8g2(U8G2_R0, 44, 43, 42, 41, 40, 39, 38, 37, /*enable=*/ 28, /*cs=*/ 32, /*dc=*/ 30, /*reset=*/ 31); // Connect WR pin with GND //U8G2_IST3020_ERC19264_F_8080 u8g2(U8G2_R0, 44, 43, 42, 41, 40, 39, 38, 37, /*enable=*/ 29, /*cs=*/ 32, /*dc=*/ 30, /*reset=*/ 31); // Connect RD pin with 3.3V //U8G2_IST3020_ERC19264_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); //U8G2_LC7981_160X80_F_6800 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 18, /*cs=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // Connect RW with GND //U8G2_LC7981_160X160_F_6800 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 18, /*cs=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // Connect RW with GND //U8G2_LC7981_240X128_F_6800 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 18, /*cs=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // Connect RW with GND //U8G2_SED1520_122X32_F u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*dc=*/ A0, /*e1=*/ A3, /*e2=*/ A2, /* reset=*/ A4); // Set R/W to low! //U8G2_T6963_240X128_F_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 17, /*cs=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // Connect RD with +5V, FS0 and FS1 with GND //U8G2_T6963_256X64_F_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 17, /*cs=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // Connect RD with +5V, FS0 and FS1 with GND //U8G2_SED1330_240X128_F_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 17, /*cs=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // Connect RD with +5V, FG with GND //U8G2_SED1330_240X128_F_6800 u8g2(U8G2_R0, 13, 11, 2, 3, 4, 5, 6, A4, /*enable=*/ 7, /*cs=*/ 10, /*dc=*/ 9, /*reset=*/ 8); // A0 is dc pin! //U8G2_RA8835_NHD_240X128_F_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 17, /*cs=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // Connect /RD = E with +5V, enable is /WR = RW, FG with GND, 14=Uno Pin A0 //U8G2_RA8835_NHD_240X128_F_6800 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 17, /*cs=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // A0 is dc pin, /WR = RW = GND, enable is /RD = E //U8G2_UC1604_JLX19264_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); //U8G2_UC1604_JLX19264_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); //U8G2_UC1608_ERC24064_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // SW SPI, Due ERC24064-1 Test Setup //U8G2_UC1608_ERC240120_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); //U8G2_UC1608_240X128_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // SW SPI, Due ERC24064-1 Test Setup //U8G2_UC1610_EA_DOGXL160_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ U8X8_PIN_NONE); //U8G2_UC1610_EA_DOGXL160_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ U8X8_PIN_NONE); //U8G2_UC1611_EA_DOGM240_F_2ND_HW_I2C u8g2(U8G2_R0, /* reset=*/ 8); // Due, 2nd I2C, DOGM240 Test Board //U8G2_UC1611_EA_DOGM240_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Due, SW SPI, DOGXL240 Test Board //U8G2_UC1611_EA_DOGXL240_F_2ND_HW_I2C u8g2(U8G2_R0, /* reset=*/ 8); // Due, 2nd I2C, DOGXL240 Test Board //U8G2_UC1611_EA_DOGXL240_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Due, SW SPI, DOGXL240 Test Board //U8G2_SSD1606_172X72_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // eInk/ePaper Display //U8G2_SSD1607_200X200_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // eInk/ePaper Display //U8G2_IL3820_296X128_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // WaveShare 2.9 inch eInk/ePaper Display, enable 16 bit mode for this display! // End of constructor list void u8g2_prepare(void) { u8g2.setFont(u8g2_font_6x10_tf); u8g2.setFontRefHeightExtendedText(); u8g2.setDrawColor(1); u8g2.setFontPosTop(); u8g2.setFontDirection(0); } void u8g2_box_frame(uint8_t a) { u8g2.drawStr( 0, 0, "drawBox"); u8g2.drawBox(5,10,20,10); u8g2.drawBox(10+a,15,30,7); u8g2.drawStr( 0, 30, "drawFrame"); u8g2.drawFrame(5,10+30,20,10); u8g2.drawFrame(10+a,15+30,30,7); } void u8g2_disc_circle(uint8_t a) { u8g2.drawStr( 0, 0, "drawDisc"); u8g2.drawDisc(10,18,9); u8g2.drawDisc(24+a,16,7); u8g2.drawStr( 0, 30, "drawCircle"); u8g2.drawCircle(10,18+30,9); u8g2.drawCircle(24+a,16+30,7); } void u8g2_r_frame(uint8_t a) { u8g2.drawStr( 0, 0, "drawRFrame/Box"); u8g2.drawRFrame(5, 10,40,30, a+1); u8g2.drawRBox(50, 10,25,40, a+1); } void u8g2_string(uint8_t a) { u8g2.setFontDirection(0); u8g2.drawStr(30+a,31, " 0"); u8g2.setFontDirection(1); u8g2.drawStr(30,31+a, " 90"); u8g2.setFontDirection(2); u8g2.drawStr(30-a,31, " 180"); u8g2.setFontDirection(3); u8g2.drawStr(30,31-a, " 270"); } void u8g2_line(uint8_t a) { u8g2.drawStr( 0, 0, "drawLine"); u8g2.drawLine(7+a, 10, 40, 55); u8g2.drawLine(7+a*2, 10, 60, 55); u8g2.drawLine(7+a*3, 10, 80, 55); u8g2.drawLine(7+a*4, 10, 100, 55); } void u8g2_triangle(uint8_t a) { uint16_t offset = a; u8g2.drawStr( 0, 0, "drawTriangle"); u8g2.drawTriangle(14,7, 45,30, 10,40); u8g2.drawTriangle(14+offset,7-offset, 45+offset,30-offset, 57+offset,10-offset); u8g2.drawTriangle(57+offset*2,10, 45+offset*2,30, 86+offset*2,53); u8g2.drawTriangle(10+offset,40+offset, 45+offset,30+offset, 86+offset,53+offset); } void u8g2_ascii_1() { char s[2] = " "; uint8_t x, y; u8g2.drawStr( 0, 0, "ASCII page 1"); for( y = 0; y < 6; y++ ) { for( x = 0; x < 16; x++ ) { s[0] = y*16 + x + 32; u8g2.drawStr(x*7, y*10+10, s); } } } void u8g2_ascii_2() { char s[2] = " "; uint8_t x, y; u8g2.drawStr( 0, 0, "ASCII page 2"); for( y = 0; y < 6; y++ ) { for( x = 0; x < 16; x++ ) { s[0] = y*16 + x + 160; u8g2.drawStr(x*7, y*10+10, s); } } } void u8g2_extra_page(uint8_t a) { u8g2.drawStr( 0, 0, "Unicode"); u8g2.setFont(u8g2_font_unifont_t_symbols); u8g2.setFontPosTop(); u8g2.drawUTF8(0, 24, "☀ ☁"); switch(a) { case 0: case 1: case 2: case 3: u8g2.drawUTF8(a*3, 36, "☂"); break; case 4: case 5: case 6: case 7: u8g2.drawUTF8(a*3, 36, "☔"); break; } } #define cross_width 24 #define cross_height 24 static const unsigned char cross_bits[] U8X8_PROGMEM = { 0x00, 0x18, 0x00, 0x00, 0x24, 0x00, 0x00, 0x24, 0x00, 0x00, 0x42, 0x00, 0x00, 0x42, 0x00, 0x00, 0x42, 0x00, 0x00, 0x81, 0x00, 0x00, 0x81, 0x00, 0xC0, 0x00, 0x03, 0x38, 0x3C, 0x1C, 0x06, 0x42, 0x60, 0x01, 0x42, 0x80, 0x01, 0x42, 0x80, 0x06, 0x42, 0x60, 0x38, 0x3C, 0x1C, 0xC0, 0x00, 0x03, 0x00, 0x81, 0x00, 0x00, 0x81, 0x00, 0x00, 0x42, 0x00, 0x00, 0x42, 0x00, 0x00, 0x42, 0x00, 0x00, 0x24, 0x00, 0x00, 0x24, 0x00, 0x00, 0x18, 0x00, }; #define cross_fill_width 24 #define cross_fill_height 24 static const unsigned char cross_fill_bits[] U8X8_PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x64, 0x00, 0x26, 0x84, 0x00, 0x21, 0x08, 0x81, 0x10, 0x08, 0x42, 0x10, 0x10, 0x3C, 0x08, 0x20, 0x00, 0x04, 0x40, 0x00, 0x02, 0x80, 0x00, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x00, 0x01, 0x40, 0x00, 0x02, 0x20, 0x00, 0x04, 0x10, 0x3C, 0x08, 0x08, 0x42, 0x10, 0x08, 0x81, 0x10, 0x84, 0x00, 0x21, 0x64, 0x00, 0x26, 0x18, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; #define cross_block_width 14 #define cross_block_height 14 static const unsigned char cross_block_bits[] U8X8_PROGMEM = { 0xFF, 0x3F, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20, 0xC1, 0x20, 0xC1, 0x20, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20, 0xFF, 0x3F, }; void u8g2_bitmap_overlay(uint8_t a) { uint8_t frame_size = 28; u8g2.drawStr(0, 0, "Bitmap overlay"); u8g2.drawStr(0, frame_size + 12, "Solid / transparent"); u8g2.setBitmapMode(false /* solid */); u8g2.drawFrame(0, 10, frame_size, frame_size); u8g2.drawXBMP(2, 12, cross_width, cross_height, cross_bits); if(a & 4) u8g2.drawXBMP(7, 17, cross_block_width, cross_block_height, cross_block_bits); u8g2.setBitmapMode(true /* transparent*/); u8g2.drawFrame(frame_size + 5, 10, frame_size, frame_size); u8g2.drawXBMP(frame_size + 7, 12, cross_width, cross_height, cross_bits); if(a & 4) u8g2.drawXBMP(frame_size + 12, 17, cross_block_width, cross_block_height, cross_block_bits); } void u8g2_bitmap_modes(uint8_t transparent) { const uint8_t frame_size = 24; u8g2.drawBox(0, frame_size * 0.5, frame_size * 5, frame_size); u8g2.drawStr(frame_size * 0.5, 50, "Black"); u8g2.drawStr(frame_size * 2, 50, "White"); u8g2.drawStr(frame_size * 3.5, 50, "XOR"); if(!transparent) { u8g2.setBitmapMode(false /* solid */); u8g2.drawStr(0, 0, "Solid bitmap"); } else { u8g2.setBitmapMode(true /* transparent*/); u8g2.drawStr(0, 0, "Transparent bitmap"); } u8g2.setDrawColor(0);// Black u8g2.drawXBMP(frame_size * 0.5, 24, cross_width, cross_height, cross_bits); u8g2.setDrawColor(1); // White u8g2.drawXBMP(frame_size * 2, 24, cross_width, cross_height, cross_bits); u8g2.setDrawColor(2); // XOR u8g2.drawXBMP(frame_size * 3.5, 24, cross_width, cross_height, cross_bits); } uint8_t draw_state = 0; void draw(void) { u8g2_prepare(); switch(draw_state >> 3) { case 0: u8g2_box_frame(draw_state&7); break; case 1: u8g2_disc_circle(draw_state&7); break; case 2: u8g2_r_frame(draw_state&7); break; case 3: u8g2_string(draw_state&7); break; case 4: u8g2_line(draw_state&7); break; case 5: u8g2_triangle(draw_state&7); break; case 6: u8g2_ascii_1(); break; case 7: u8g2_ascii_2(); break; case 8: u8g2_extra_page(draw_state&7); break; case 9: u8g2_bitmap_modes(0); break; case 10: u8g2_bitmap_modes(1); break; case 11: u8g2_bitmap_overlay(draw_state&7); break; } } void setup(void) { u8g2.begin(); } void loop(void) { // picture loop u8g2.clearBuffer(); draw(); u8g2.sendBuffer(); // increase the state draw_state++; if ( draw_state >= 12*8 ) draw_state = 0; // deley between each page delay(100); }
속도는 U8g 의 Fast I2C 정도는 아니지만,
그리 느린 속도는 아니면서 arduino 의 led 는 점멸하지 않습니다.
10. Reference
위에서 열거되지 않은 부분은, 주로 아래 link 들을 참고하였습니다.
- https://forum.arduino.cc/index.php?topic=403234.0
- https://github.com/squix78/esp8266-oled-ssd1306
- http://www.instructables.com/id/Monochrome-096-i2c-OLED-display-with-arduino-SSD13/
FIN
역시 사람은 오감으로 느껴야지만 이해가 갑니다.
'Hardware' 카테고리의 다른 글
Hardware | TSSR 3.5mm audio jack 구매하기 (0) | 2017.09.19 |
---|---|
Hardware | Adafruit SSD1306 128x64 1.3" monochrome OLED 를 사용해보자 (0) | 2017.09.19 |
Hardware | SSD1331 96x64 full color OLED 를 사용해보자 (0) | 2017.09.07 |
Hardware | FTDI Serial Adapter 를 사용해 보자 (0) | 2017.09.05 |
Hardware | NEO-6M GPS 를 구동해 보자 (2) | 2017.09.05 |
1. Tistory
iPhone 에서 찍은 동영상을 Tistory 에 올리다 보면,
스마트폰을 분명 가로로 눕혀서 찍었는데도 불구하고 세로로 올라가는 경우가 있습니다.
포탈에서 검색해 보면,
여러 상용이나, 무료 소프트웨어에서 "회전" 시켜주는 방법이 소개됩니다.
다만,
상용은 돈을 내야 하고, 무료 소프트웨어더라도 이 "회전" 이 들어가면 유료버전을 사용하라고 뜹니다. (아놔)
"내가 이거 돈들지 않고 고쳐본다" 라는 오기가 생기더군요.
2. FFmpeg
예전 미디어 스트리밍 업무에 관여하고 있을 시,
FFmpeg 라는 command line 어플을 알게 되었습니다.
여러 상용 transcoding / encoding 소프트웨어가 시장에 나와 있지만,
입맛에 맞게 in-house 개발을 하려면 FFmpeg 밖에 답이 없어 보였습니다.
그래, FFmpeg 라면 분명 뭐가 있을꺼야 라는 생각으로 작업을 시작해 봅니다.
일단 아래 link 에서 최신판 FFmpeg 를 다운로드 받습니다.
- https://www.ffmpeg.org/download.html
참고로 FFmpeg 는 update 가 잘 되는 편이라,
예전 버전을 가지고 있으면 기능을 원활하게 구현하지 못하거나 더 좋은 방식을 못쓰는 경우가 있습니다.
꼭 최신판을 받으세요.
Windows 라면, directory 를 하나 만들어서 압축을 풀어 놓습니다.
실행 파일은 bin 폴더 밑에 ffmpeg.exe 파일 입니다.
자 시작해 볼까요?
ffmpeg -i input_filename.mov -c copy -metadata:s:v:0 rotate=0 output_filename.mov
실제로 실행시킨 화면 입니다.
"ffmpeg.exe" 가 실행되면서 동영상 파일의 여러 property 를 보여주는데,
"rotate : 90" 로 되어 있는 것을 확인할 수 있습니다.
metadata 만 바꾸어 주는 것이므로, 실행은 바로 끝나고 화일 용량도 거의 같습니다.
4. data 자체를 실제로 회전시키고 re-encoding 하기
부제목 그대로, data 자체를 회전시키면서 재 encoding 하는 방법입니다.
실행 command line 은 다음과 같습니다.
ffmpeg -i input_filename.mov -vf "transpose=2" output_filename.mov
여기서 중요한 key 는 "transpose=X" 입니다.
0 = 90CounterCLockwise and Vertical Flip (default) 1 = 90Clockwise 2 = 90CounterClockwise 3 = 90Clockwise and Vertical Flip
원본 소스가 시계방향 90 도로 틀어져 있으므로,
옵션 2를 선택하여 시계 반대방향 90 도로 지정하였습니다.
아래는 실제 실행시킨 화면 입니다.
metadata 단순 수정과는 다르게, 여러 정보가 쏟아져 나옵니다.
이는 실제로 re-encoding 을 통하여 모든 동영상 data 를 다시 구성했기 때문이지요.
80MB 짜리 mov 파일을 랩탑에서 돌리는데, 약 3분정도 소요된것 같습니다.
encoder 도 원본은 H.264 인데,
FFmpeg 를 거치면서 Lavc57 로 변경되었습니다. 아무래도 CODEC license 문제를 피해가기 위함인 듯 하네요.
완료 파일도 20MB 로 줄어들었습니다.
줄어들어서 좋긴 하지만,
인코딩 횟수를 더하면서 동영상 화질의 열화를 가져다 줄 듯 합니다.
5. 결과
* ORIGINAL
Tistory 에 바로 올리면 이렇게, 오른쪽 90도 틀어진 상태로 올라가게 됩니다.
* METADATA 삭제
metadata 만 삭제한 버전입니다.
문제 없이 원래대로 돌아 왔죠?
* RE-ENCODING
"transpose=2" 를 사용하여 re-encoding 시킨 파일 입니다.
잘 되돌려 놓기는 했습니다만, 살~짝 위의 metadata 와 비교시 화질 열화가 있습니다.
다만, 80MB --> 20MB 로 줄이면서 거의 차이가 없는 정도이므로,
시간이 허락한다면 이렇게 해도 문제는 없겠죠? 선택은 사용자가 판단하면 될 듯 해요.
6. 그럼 180 도 회전은?
180도 회전이 필요한 동영상은 "vflip + hflip" 으로 하면 될것 같습니다.
- https://ffmpeg.org/ffmpeg-filters.html
다만, 이렇게 하면 화면이 뭉개져 버립니다. 이게 FFmpeg 를 사용하는게 어려운 점인것 같아요.
(Linux 버전에서는 테스트해보지 못했습니다.)
180도 회전을 하고싶은 경우는 아래와 같은 순서로 해야 합니다.
1. rotate=0 를 먹여서 metadata 를 reset 한다. (rotate=180 이 먹지 않는다.)
2. vflip + hflip 을 이용하여 180 도 회전 효과를 낸다.
명령어는 다음과 같이 하면 됩니다.
ffmpeg.exe -i R:\White_LED.MOV -c copy -metadata:s:v:0 rotate=0 R:\out.MOV ffmpeg.exe -i R:\Out.MOV -vf "vflip,hflip" R:\vhflip.MOV
아래는 처음 원본 source 이고, 그 다음은 "rotate=0 --> vflip + hflip" 한 결과 입니다.
우선 "rotate=0" 입니다. 상하가 그대로죠?
아래는 최종적으로 "vflip + hflip" 한 결과 입니다.
잘 되죠? :-)
화질 저하는 거의 느끼지 못할만큼 있지만, 용량은 re-encoding 을 통하여 1/4 이상 줄었습니다.
7. Reference
아래 link 는 FFmpeg 을 이용한 회전 사용법에 대해 알아본 stack overflow 입니다.
- https://stackoverflow.com/questions/20664460/remove-rotate-metadata-from-mp4
- https://stackoverflow.com/questions/3937387/rotating-videos-with-ffmpeg/9570992#9570992
FIN
후훗, 이제 걱정 없구만.
다 덤벼~!
'Software' 카테고리의 다른 글
Software | 회로설계 프로그램 EAGLE (2) | 2018.09.04 |
---|---|
Linux | Ubuntu-Mate 를 원격 데스크탑으로 사용해 보자 (0) | 2018.05.13 |
Software | u-blox 의 GPS 어플을 사용해 보자 (0) | 2017.09.05 |
Software | Visual Studio Code 를 사용해 보자 (0) | 2017.09.01 |
Software | IntelliJ IDEA 를 사용해 보자 (0) | 2017.08.30 |
1. Full Color OLED
Arduino 에 연결하여 표현해 주는 OLED 가 있습니다.
센서값을 보여주는 모니터링용으로는 괜찮아 보입니다.
Monochrome 제품은 이미 테스트 해봤습니다.
- http://chocoball.tistory.com/entry/Hardware-SSD1306-128x64-monochrome-OLED
0.95 크기를 가지는 OLED 는 대략 세가지가 있는것 같습니다.
하나는 위의 Monochrome 이고,
두번째는 윗쪽이 노란색이고 밑에가 파란색인 제품.
마지막은 full color 제품 입니다.
AliExpress 에서 찾아보니 6.84 USD 로 판매되고 있습니다.
재미있는 것은, 제품이 SSD1306 드라이버라고 사이트에 올라와 있는데,
SSD1306 은 Monochrome 제품용이고, full color 는 SSD1331 드라이버 입니다.
결국 사이트에 잘못 올린거지요.
SSD1331 용 full color OLED 는 10 USD 정도 인데, SSD1306 으로 검색되는 full color OLED 는 7 USD 정도 이니,
검색은 SSD1306 으로 되는 full color OLED 를 구매하면 이득입니다.
이번 글에서도 "SSD1331" 드라이버에 맞는 sketch 를 이용했습니다.
2. 도착
도착샷은 다음과 같습니다.
창이 달린 모니터 있다 보니, 뽁뽁이로 잘 쌓여서 왔습니다.
오호이. 상태는 좋아 보입니다.
제품의 줌샷 입니다.
뒷면입니다.
SSD1331 datasheet 는 다음과 같습니다.
아래 link 를 많이 참조 했습니다.
- http://educ8s.tv/arduino-color-oled-display-tutorial/
3. Pinout
Arduino 와 pin 연결 정보 입니다.
SSD1331 | Arduino Nano ---------------------------- GND | GND VCC | 3.3V SCL | D13 SDA | D11 RES | D9 DC | D8 CS | D10 ----------------------------
Layout 은 다음과 같습니다.
참조 Youtube 동영상에서 캡춰한 내용이 가장 잘 맞는것 같네요.
3. Library
아래 GitHub 에서 SSD1331 라이브러리를 다운로드 받습니다.
- https://github.com/adafruit/Adafruit-SSD1331-OLED-Driver-Library-for-Arduino
"/Arduino/Library/" 폴더에 다운로드 받은 파일을 넣어도 좋고,
아래처럼 Arduino IDE 에서 검색해서 install 할 수도 있습니다.
"Sketch > Include Library > Manage Libraries..." 에서 "gfx" 와 "SSD1331" 을 검색하면 install 되어 있으면 OK.
없으면 install 하면 됩니다.
"gfx" 를 검색하니, Adafruit GFX 가 이미 깔려 있네요.
"SSD1331" 을 검색하니, Adafruit SSD1331 OLED Driver Library for Arduino 도 이미 깔려 있습니다.
4. Sketch
"File > Examples > Adafruit SSD1331 OLED Driver Library for Arduino > test" 의 소스 입니다.
/*************************************************** This is a example sketch demonstrating the graphics capabilities of the SSD1331 library for the 0.96" 16-bit Color OLED with SSD1331 driver chip Pick one up today in the adafruit shop! ------> http://www.adafruit.com/products/684 These displays use SPI to communicate, 4 or 5 pins are required to interface Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! Written by Limor Fried/Ladyada for Adafruit Industries. BSD license, all text above must be included in any redistribution ****************************************************/ // You can use any (4 or) 5 pins #define sclk 13 #define mosi 11 #define cs 10 #define rst 9 #define dc 8 // Color definitions #define BLACK 0x0000 #define BLUE 0x001F #define RED 0xF800 #define GREEN 0x07E0 #define CYAN 0x07FF #define MAGENTA 0xF81F #define YELLOW 0xFFE0 #define WHITE 0xFFFF #include "Adafruit_GFX.h" #include "Adafruit_SSD1331.h" #include "SPI.h" // Option 1: use any pins but a little slower Adafruit_SSD1331 display = Adafruit_SSD1331(cs, dc, mosi, sclk, rst); // Option 2: must use the hardware SPI pins // (for UNO thats sclk = 13 and sid = 11) and pin 10 must be // an output. This is much faster - also required if you want // to use the microSD card (see the image drawing example) //Adafruit_SSD1331 display = Adafruit_SSD1331(cs, dc, rst); float p = 3.1415926; void setup(void) { Serial.begin(9600); Serial.print("hello!"); display.begin(); Serial.println("init"); uint16_t time = millis(); display.fillScreen(BLACK); time = millis() - time; Serial.println(time, DEC); delay(500); lcdTestPattern(); delay(1000); display.fillScreen(BLACK); display.setCursor(0,0); display.print("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur adipiscing ante sed nibh tincidunt feugiat. Maecenas enim massa"); delay(1000); // tft print function! tftPrintTest(); delay(2000); //a single pixel display.drawPixel(display.width()/2, display.height()/2, GREEN); delay(500); // line draw test testlines(YELLOW); delay(500); // optimized lines testfastlines(RED, BLUE); delay(500); testdrawrects(GREEN); delay(1000); testfillrects(YELLOW, MAGENTA); delay(1000); display.fillScreen(BLACK); testfillcircles(10, BLUE); testdrawcircles(10, WHITE); delay(1000); testroundrects(); delay(500); testtriangles(); delay(500); Serial.println("done"); delay(1000); } void loop() { } void testlines(uint16_t color) { display.fillScreen(BLACK); for (int16_t x=0; x < display.width()-1; x+=6) { display.drawLine(0, 0, x, display.height()-1, color); } for (int16_t y=0; y < display.height()-1; y+=6) { display.drawLine(0, 0, display.width()-1, y, color); } display.fillScreen(BLACK); for (int16_t x=0; x < display.width()-1; x+=6) { display.drawLine(display.width()-1, 0, x, display.height()-1, color); } for (int16_t y=0; y < display.height()-1; y+=6) { display.drawLine(display.width()-1, 0, 0, y, color); } display.fillScreen(BLACK); for (int16_t x=0; x < display.width()-1; x+=6) { display.drawLine(0, display.height()-1, x, 0, color); } for (int16_t y=0; y < display.height()-1; y+=6) { display.drawLine(0, display.height()-1, display.width()-1, y, color); } display.fillScreen(BLACK); for (int16_t x=0; x < display.width()-1; x+=6) { display.drawLine(display.width()-1, display.height()-1, x, 0, color); } for (int16_t y=0; y < display.height()-1; y+=6) { display.drawLine(display.width()-1, display.height()-1, 0, y, color); } } void testdrawtext(char *text, uint16_t color) { display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0,0); for (uint8_t i=0; i < 168; i++) { if (i == '\n') continue; display.write(i); if ((i > 0) && (i % 21 == 0)) display.println(); } } void testfastlines(uint16_t color1, uint16_t color2) { display.fillScreen(BLACK); for (int16_t y=0; y < display.height()-1; y+=5) { display.drawFastHLine(0, y, display.width()-1, color1); } for (int16_t x=0; x < display.width()-1; x+=5) { display.drawFastVLine(x, 0, display.height()-1, color2); } } void testdrawrects(uint16_t color) { display.fillScreen(BLACK); for (int16_t x=0; x < display.height()-1; x+=6) { display.drawRect((display.width()-1)/2 -x/2, (display.height()-1)/2 -x/2 , x, x, color); } } void testfillrects(uint16_t color1, uint16_t color2) { display.fillScreen(BLACK); for (int16_t x=display.height()-1; x > 6; x-=6) { display.fillRect((display.width()-1)/2 -x/2, (display.height()-1)/2 -x/2 , x, x, color1); display.drawRect((display.width()-1)/2 -x/2, (display.height()-1)/2 -x/2 , x, x, color2); } } void testfillcircles(uint8_t radius, uint16_t color) { for (uint8_t x=radius; x < display.width()-1; x+=radius*2) { for (uint8_t y=radius; y < display.height()-1; y+=radius*2) { display.fillCircle(x, y, radius, color); } } } void testdrawcircles(uint8_t radius, uint16_t color) { for (int16_t x=0; x < display.width()-1+radius; x+=radius*2) { for (int16_t y=0; y < display.height()-1+radius; y+=radius*2) { display.drawCircle(x, y, radius, color); } } } void testtriangles() { display.fillScreen(BLACK); int color = 0xF800; int t; int w = display.width()/2; int x = display.height(); int y = 0; int z = display.width(); for(t = 0 ; t <= 15; t+=1) { display.drawTriangle(w, y, y, x, z, x, color); x-=4; y+=4; z-=4; color+=100; } } void testroundrects() { display.fillScreen(BLACK); int color = 100; int i; int t; for(t = 0 ; t <= 4; t+=1) { int x = 0; int y = 0; int w = display.width(); int h = display.height(); for(i = 0 ; i <= 24; i+=1) { display.drawRoundRect(x, y, w, h, 5, color); x+=2; y+=3; w-=4; h-=6; color+=1100; } color+=100; } } void tftPrintTest() { display.fillScreen(BLACK); display.setCursor(0, 5); display.setTextColor(RED); display.setTextSize(1); display.println("Hello World!"); display.setTextColor(YELLOW, GREEN); display.setTextSize(2); display.print("Hello Wo"); display.setTextColor(BLUE); display.setTextSize(3); display.print(1234.567); delay(1500); display.setCursor(0, 5); display.fillScreen(BLACK); display.setTextColor(WHITE); display.setTextSize(0); display.println("Hello World!"); display.setTextSize(1); display.setTextColor(GREEN); display.print(p, 5); display.println(" Want pi?"); display.print(8675309, HEX); // print 8,675,309 out in HEX! display.print(" Print HEX"); display.setTextColor(WHITE); display.println("Sketch has been"); display.println("running for: "); display.setTextColor(MAGENTA); display.print(millis() / 1000); display.setTextColor(WHITE); display.print(" seconds."); } void mediabuttons() { // play display.fillScreen(BLACK); display.fillRoundRect(25, 10, 78, 60, 8, WHITE); display.fillTriangle(42, 20, 42, 60, 90, 40, RED); delay(500); // pause display.fillRoundRect(25, 90, 78, 60, 8, WHITE); display.fillRoundRect(39, 98, 20, 45, 5, GREEN); display.fillRoundRect(69, 98, 20, 45, 5, GREEN); delay(500); // play color display.fillTriangle(42, 20, 42, 60, 90, 40, BLUE); delay(50); // pause color display.fillRoundRect(39, 98, 20, 45, 5, RED); display.fillRoundRect(69, 98, 20, 45, 5, RED); // play color display.fillTriangle(42, 20, 42, 60, 90, 40, GREEN); } /**************************************************************************/ /*! @brief Renders a simple test pattern on the LCD */ /**************************************************************************/ void lcdTestPattern(void) { uint32_t i,j; display.goTo(0, 0); for(i=0;i<64;i++) { for(j=0;j<96;j++) { if(i>55){display.writeData(WHITE>>8);display.writeData(WHITE);} else if(i>47){display.writeData(BLUE>>8);display.writeData(BLUE);} else if(i>39){display.writeData(GREEN>>8);display.writeData(GREEN);} else if(i>31){display.writeData(CYAN>>8);display.writeData(CYAN);} else if(i>23){display.writeData(RED>>8);display.writeData(RED);} else if(i>15){display.writeData(MAGENTA>>8);display.writeData(MAGENTA);} else if(i>7){display.writeData(YELLOW>>8);display.writeData(YELLOW);} else {display.writeData(BLACK>>8);display.writeData(BLACK);} } } }
5. 동작
위의 sketch 를 업로드 하고 pin 을 잘 연결하면, 아래와 같은 동작을 보여줍니다.
글씨, 배경색, 크기 등 여러가지를 확인해 볼 수 있습니다.
그림들도 잘 표현이 됩니다. 물론 컬러로.
SPI 프로토콜이라서 그런지, Monochorme 의 I2C 인터페이스보다는 확실히 빠른 성늘을 보여주네요.
다음은 동영상 입니다.
FIN
화면의 상하단의 색이 다른 OLED 는 SSD1306 을 사용한지라,
부분 컬러이긴 하지만, 더이상 OLED 는 구매하지 않아도 될 듯 해요.
'Hardware' 카테고리의 다른 글
Hardware | Adafruit SSD1306 128x64 1.3" monochrome OLED 를 사용해보자 (0) | 2017.09.19 |
---|---|
Hardware | SSD1306 128x64 monochrome OLED 를 사용해보자 (0) | 2017.09.14 |
Hardware | FTDI Serial Adapter 를 사용해 보자 (0) | 2017.09.05 |
Hardware | NEO-6M GPS 를 구동해 보자 (2) | 2017.09.05 |
Hardware | Probe Clip 을 사용해 보자 (0) | 2017.08.28 |
1. u-blox
생소한 이름인 u-blox 라는 회사는 GPS 칩을 만드는 스위스 회사 이름입니다.
- https://en.wikipedia.org/wiki/U-blox
일전에 NEO-6M 이라는 GPS breakout board 를 이용해 놀아 봤는데, 그 메인 칩을 제조하는 회사지요.
GPS 가지고 노는 내용은 아래 link 를 참고하세요.
- http://chocoball.tistory.com/entry/Hardware-NEO6M-GPS
2. u-center
GPS 칩을 만드는 회사가 그것을 활용하는 소프트웨어도 제공하고 있습니다.
이름하야 "u-center". 다운로드는 다음 link 에서 받을 수 있습니다.
- https://www.u-blox.com/en/product/u-center-windows
Android 버전도 있네요. 저는 Windows 에서만 사용해 봤습니다.
사용자 manual 은 다운로드 받아 놨습니다.
- u-center_UserGuide_(UBX-13005250).pdf
3. 설치
파일을 받고 설치를 시작합니다.
먼저 언어를 선택하고.
본격적으로 설치를 시작합니다.
라이센스에 Agree 해줍니다.
Standard Driver 와 Sensor Driver 를 설치하는 부분입니다.
Sensor Driver 는 breakout board 가 없을 경우를 말하는건가? 잘 모르겠습니다.
의심스러우면 걍 Standard Driver 를 쓰라고 합니다. 예...
인스톨할 디렉토리를 선택하고. (어차피 디폴트)
완료~!!!
인스톨된 버전을 확인해 보면 아래와 같습니다. 8.26 이네요.
회사 주소가 Switzerland 라고 나와 있습니다. 가보고 싶네요.
회사 주소는 여기라는 군요.
- u-blox AG Zürcherstrasse 68 8800 Thalwil Switzerland
궁금해서 Google Maps 의 street view 로 확인해 봤습니다.
좋은 동네같아요. 깔끔하고. 이런곳에서 일하면 인생이 윤택해질것 같습니다.
4. 기능
실행을 시키면 이런 식으로 확인 할 수 있습니다.
와~~~!!! 여러 정보가 보입니다.
처음에는 미국 위성만 잔뜩 보이더니만, 가끔 일본 위성도 뜹니다.
아쉽게도 한국 위성은 보이지 않습니다.
Sky View 에서는 방위 및 각도별로 표시해 줍니다.
이동 괘적도 보여주네요.
신호 강도에 대한 Histogram 을 보여주는 듯 합니다.
한국 하늘에서 측정한 것인데, 지구가 둥글다 보니, 다른곳의 위성도 같이 잡히는게 신기했습니다.
Satellite Signal History 에서는 각 위성에서 받는 신호 세기를 보여줍니다.
Statistic View 에서는 수신한 신호에서 유용한 data 를 뽑아서 보여줍니다.
실제적으로 이 data 를 가공하여 유용하게 사용될 것 같습니다.
현상태의 data 를 dump 뜨는 기능도 가지고 있습니다.
아마 문제가 생겼을 시에 사용되는 기능일 듯 합니다.
Chart 에서는 data 를 여러 형식으로 보여줍니다.
아래는 해발 높이를 보여주는 듯 합니다.
Messages 에서는 여러 data 의 현재 상태를 나타내 줍니다.
5. 정지한 상태에서 확인
정지한 상태에서 프로그램을 돌려 봤습니다.
베란다 난간에 외부 안테나를 설치하고 u-center 를 돌려 봅니다.
오오오! 신호를 잡아서 현재의 위치 및 시간을 알려줍니다.
대박입니다. 이렇게 비주얼하게 볼 수 있다니.
그리고 GPS 를 통하여 이루어지는 data 는 엄청 여러가지가 있네요.
6. 움직이면서 확인
차 위에 설치해도 되고 dashboard 에 설치해도 됩니다.
외부 antenna 는 밑부분이 자석으로 되어 있어서, 차의 어느곳에나 착 달라 붙어 고정됩니다.
빵판은 데쉬보드 위에 올려 놨습니다.
PC와의 연결은 FTDI 호환보드인 CP2102 입니다.
- http://chocoball.tistory.com/entry/Hardware-FTDI-FT232RL-using
이동하면서 측정했더니 확연히 다른 모습을 보여줍니다.
방위가 실시간으로 바뀌고, 속도계가 반응하기 시작했습니다!!!
외부 안테나를 사용해도 되나, 길게 늘릴 필요가 없어 NEO-6M 에 동봉된 길이가 짧은 안테나를 차 내부에서도 사용해 봤습니다.
달리면서 측정하니, GPS 의 진정한 가치를 알게 되는것 같습니다.
7. firmware update
원래 NEO-6M 제품을 사용하고 있으나, u-center 에서는 "u-blox 7" 으로 인식하고 있습니다.
NEO-6MV2 라고 표시되어 있는 만큼 그 사이에 chip 이 upgrade 되어서 그러는지 모르겠습니다.
메뉴의 "firmware update ..." 가 있어서 실행해 봤습니다.
Firmware image 는 u-blox 사이트에서 다운로드 받았고,
Flash Information Structure 파일인 "flash.xml" 은 u-center 프로그램 파일이 설치된 폴더에 있습니다.
결과는 에러...
사이트에서 제품 특징들에 대해 확인해 봤습니다.
이런... firmware update 를 할 수 있는 flash 가 장착된 칩은 "M" 이 붙으면 안되고,
"N" 이 붙어야 합니다.
- https://www.u-blox.com/en/product/neo-7-series
더욱이, NEO-6 시리즈에서는 firmware update 를 할 수 있는 버전이 없다는 사실...
- https://www.u-blox.com/en/product/neo-6-series
만일 firmware update 가 가능하다면, 아래처럼 Extenstion(s) 부분에서 FWVER 항목이 나와야 할 것 같습니다.
(구글링 해서 찾아 봄)
Messages 의 MON-VER 를 확인해 보면,
7 시리즈는 맞는것 같은데, FWVER 옵션이 보이지 않습니다.
바로 포기합니다. (이미 해볼껀 다 해봤슴)
NEO-6M 을 샀는데 7 serise 가 들어있는 것만 해도 희한한 상황입니다.
FIN
GPS 를 통하여 지상에서 위성을 통한 무료 data 를 받아 이렇게까지 활용할 수 있다는 것이 신기했습니다.
GPS 는 문명의 이기임에는 확실해 보입니다.
NEO-M8N 보드를 구입해서 확인해 보고 싶어집니다.
'Software' 카테고리의 다른 글
Linux | Ubuntu-Mate 를 원격 데스크탑으로 사용해 보자 (0) | 2018.05.13 |
---|---|
Software | FFmpeg 를 사용하여 동영상을 회전시켜 보자 (0) | 2017.09.14 |
Software | Visual Studio Code 를 사용해 보자 (0) | 2017.09.01 |
Software | IntelliJ IDEA 를 사용해 보자 (0) | 2017.08.30 |
Software | Google AdSense 가입 및 설정하기 (0) | 2017.04.30 |
1. Flash Programming
무선 WIFI 모듈인 ESP8266 을 사용하여 wireless speaker 를 제작하려고 준비하고 있습니다.
그러기 위해서는 ESP8266 의 펌웨어를 프로그래밍 해줘야 하는데,
이를 위해서는 Serial Converter / Adapter 가 필요합니다.
이 Serial Adapter 는, 펌웨어 관련된 모든것에 사용되는 것 같습니다.
미리 알았더라면, 예전에 Flashrom writer 시에 사용했을 터인데...
- http://chocoball.tistory.com/entry/Hardware-flashROM-fix
이런 다방면의 활용성을 가지고 있으므로, 한두개 구비해 놓은게 좋을것 같다고 생각되어
한꺼번에 2개를 구입합니다.
동일한 제품을 구매하면 재미가 없으므로, 각각 다른 chip 을 사용한 adapter 를 구매합니다.
2. Silicon Labs CP2102
FT232 대용으로 나온 chip 입니다.
동작은 완벽히 호환되었습니다.
Spec. Sheet 는 다음과 같습니다.
기존의 FT232RL breakout board 와 비교하여 pinout 들이 간략화 되어 있어
보드 자체의 크기도 작고, chip 도 소형화 되어 있습니다.
구매는 아래 link 에서 진행했어요.
가격은 1.02 USD 로 부담이 없고 무료 배송입니다.
아래는 사이트에서 보여준 사진 입니다.
Chip 에 SILABS CP2102 라고 적혀 있는 것을 확인할 수 있습니다.
도착샷 들입니다.
보통은 USB 인터페이스 지만, 이 부품은 microUSB 입니다.
뒷면입니다.
Windows 에 USB를 통하여 연결하면, 알아서 드라이버를 잡아 줍니다.
장치 관리자에서 COM port 를 꼭 확인하여, 나중에 어플에서 잡아줄 때 참고하면 되겠습니다.
3. FTDI FT232RL
그 이름 그대로의 제품 입니다.
Chip 은 FT232RL 이네요.
가격은 1.65 USD 로 역시 저렴합니다.
Spec. Sheet 는 다음과 같습니다.
참고로 fake FT232RL chip 이 존재한다 합니다. Fake 제품이라고 해서 문제는 발생되지 않는다고 합니다.
다만, 원래 생산자의 시장을 잠식하면서, 막대한 손해를 끼치겠죠.
가장 단순한 판변법은, chip 상면에 세겨진 각인이 laser 로 쓰였는지, 프린팅 되었는지의 구분이라고 하네요.
- https://zeptobars.com/en/read/FTDI-FT232RL-real-vs-fake-supereal
Chip 을 줌업 해봤습니다.
잘 모르겠지만 laser 로 쓰여진 듯 합니다. 그 사이에 fake chip 생산자의 기술이 올라갔을지 모르겠습니다.
구입은 아래 link 에서 진행했습니다.
일반적인 포장으로 잘 왔습니다.
정전기 방지 포장도 되어 있습니다.
FTDI 용으로는 가장 많이 쓰이는 보드가 아닐까 합니다.
아래는 제품 소개 사이트 뒷면 :-D
Windows driver 는 자동으로 잡힙니다.
처음에는 "FT232R USB UART" 로 인식한 후, driver 가 인스톨 완료 되면 아래와 같이, "USB Serial Converter / Port" 로 변경됩니다.
장치 관리자에서는 "USB Serial Port" 라고 표시됩니다.
4. 구동
NEO-6M GPS 와 연결해본 사진 입니다.
사진에는 FT232RL 만 보이지만, CP2102 로도 완벽히 동일하게 작동하였습니다.
NEO-6M 과의 자세한 동작 영상들은 아래 link 에서 확인해 보세요.
- http://chocoball.tistory.com/entry/Software-ublox-GPS-application
FIN
정신을 차려 보니, 점점 많은 부품들이 제 주위에 쌓여가고 있습니다.
'Hardware' 카테고리의 다른 글
Hardware | SSD1306 128x64 monochrome OLED 를 사용해보자 (0) | 2017.09.14 |
---|---|
Hardware | SSD1331 96x64 full color OLED 를 사용해보자 (0) | 2017.09.07 |
Hardware | NEO-6M GPS 를 구동해 보자 (2) | 2017.09.05 |
Hardware | Probe Clip 을 사용해 보자 (0) | 2017.08.28 |
Hardware | Gyroscope GY-521 MPU-6050 을 사용해 보자 (0) | 2017.08.20 |
1. GPS
우리 생활에 이제는 필수가 된 GPS.
모바일 기기라면 이제 GPS 는 어디든 달려 있는 시대 입니다.
이게 Arduino 용의 breakout board 로 나와 줬네요.
센서에 목말라 있는 저로써는 꼭 구동해 보고싶은 센서 입니다.
2. 주문
AliExpress 에서 검색해 보면, 대략 3가지 제품으로 나뒵니다.
- Drone 용 소형 GPS : NEO-M8N
- 저가용 GPS : NEO-6M
- 그 외 안테나, 연장선 등의 부품
대략 저가용 GPS 인 NEO-6M 을 빼면, NEO-M8N 인데, 1만원이 넘어가는 나름 고가 센서가 됩니다.
우선 구동만을 확인해 볼 예정이므로, NEO-6M 을 구입합니다.
* NEO-6M 본체
6천원 정도면, 밥 한끼 정도의 가격이므로, 취미의 즐거움을 위해 희생해 봅니다.
구입은 Arduino 취미를 시작한 작년 말에 구입했지만,
정작 사용해 보기까지는 시간이 걸렸습니다.
그 이유는 달려있는 안테나가 너무 짧아, 연장선을 구입하고, 다른 센서가지고 놀면서 늘어졌습니다.
GPS 는 좀 진득하게 사용해 봐야 할 것 같았거든요.
* 안테나 연장
PC 에 연결하여 확인하려면 외부로 가지고 나가야 하는데, laptop 이 필수 입니다.
구동 완료가 될 때까지 매번 밖에 나갈 수는 없으므로 연장 안테나를 구입합니다.
* 커넥터
연장 안테나의 끝 단자인 SMA Male connector 랑 breakout board 와의 연결을 위해,
SMA female connector 를 구입합니다.
다만 여기서 사고가 발생합니다.
바로 breakout board 에 있는 단자 크기를 몰라, 그냥 주문했더니, 맞지 않았습니다.
원래 breakout board 의 안테나 단자를 감싸야 하는데, 그 속으로 들어가버릴 정도로 작았습니다.
구매 사이트 사진에는 MHF-4 도 표시되어 있지만, 사실은 U. FL 규격을 구입해야 했었습니다.
결국 U. FL 규격의 SMA female 단자도 나중에 구입하지만,
또 기다려야 하니 좀이 쑤셔서 그냥 진행해 보기로 합니다.
3. 도착
도착은 3주정도 걸린 듯 합니다.
구성품은 NEO-6M breakout board 와 U. FL 커넥터가 달린 안테나 로 되어 있습니다.
여기에 문제의 "SMA female : MHF-4" 점퍼 입니다.
배송은 참 잘 왔습니다.
MHF-4 connector 는 WIFI 모듈에 자주 쓰이는 규격이라 아니, 나중에 또 쓸 일이 있겠죠?
판매자의 별 5개 요청 편지.
AliExpress 입점상들도 경쟁이 치열해지고 평가에 의해 매출이 달라지므로 신경을 많이 쓰는것 같습니다.
역시 글로벌로 장사를 하면, 사용자 피드백의 중요함이 사업에 있어서 크리티컬 하다는 것을 알 수 있습니다.
장사꾼들인 중국인들에게는 배울게 많습니다.
연장 안테나 모듀입니다.
배송은 잘 왔습니다.
이쪽 면이 자석으로 되어 있어서 차량이나 난간에 잘 고정이 됩니다.
난간에는 이렇게 설치 되었습니다.
왼쪽의 안테나는 FlightAware 용으로 세워진 안테나 입니다.
- http://chocoball.tistory.com/entry/Hardware-PiAware-FlightAware
4. MHF-4
문제의 MHF-4 단자에 대해 살펴보기로 합니다.
구성품으로 달려있던 안테나 단자와 비교샷 입니다.
크기 자체의 차이로 따져 보면, 구성품의 connector 는 "U. FL" 규격으로 보입니다.
자세히 들여다 보면, 중심부에 꽂히는 심의 크기는 양쪽다 (MHF-4 / U. FL) 같아 보입니다.
여기서 착안하여 그냥 사용해 보기로 합니다.
원래는 이렇게 연결해서 사용됩니다.
U. FL 규격으로, breakout board 와 연결된 모습입니다.
외곽 금속을 커넥터가 잘 감싸 줘서 확실하게 고정이 되는 구조입니다.
이렇게 연결하면 손톱으로 튕기지 않는 한, 잘 붙어 있습니다.
SMA female : MHF-4 규격의 점퍼와 연결한 모습입니다.
Breakout 보드쪽 커넥터의 외경이 점퍼 외경을 반대로 감싸는 구조가 됩니다.
전기적 신호는 문제 없겠지만, 많이 헐겁습니다. 조금만 힘이 가해져도 금방 분리가 되어 버립니다. (진행하면서 가장 스트레스)
다시 주문한 "SMA-female : U. FL" 단자는 아직 도착하지 않았지만,
아래 구성처럼 연결하여 진행합니다.
5. Arduino 와 연결
Pin 들을 납땜해서 사용해도 되지만, 향후 어떤 보드에 실장하게 될 지 모르는지라,
납땜하지 않고 Probe Clip 을 이용하여 연결합니다.
Probe Clip 에 대해서는 다음 link 를 참조해 주세요.
- http://chocoball.tistory.com/entry/Hardware-Probe-Clip
Arduino 와 연결된 모습입니다.
6. Layout
Pin 연결 정보 입니다.
NEO-6M | Arduino Nano ---------------------------- VCC | 3.3V RX | D9 TX | D10 GND | GND ----------------------------
보드 연결선은 다음과 같이 하면 됩니다.
7. Libaray 및 Sketch
여기서부터는 아래 사이트를 참고 하였습니다.
- http://www.instructables.com/id/How-to-Communicate-Neo-6M-GPS-to-Arduino/
사전에 필요한 Library 는 다음 두가지 입니다.
미리 Arduino Library 폴더에 카피해 놓습니다.
* TinyGPS
- http://arduiniana.org/libraries/tinygps/
- https://github.com/mikalhart/TinyGPS
* SoftwareSerial
- https://cdn.instructables.com/ORIG/F8C/OHR4/IVHQK4BI/F8COHR4IVHQK4BI.rar
위의 두 Library 가 준비되었다면, 아래 sketch 를 업로드해서 구동시킬 수 있습니다.
/********************* *10 to GPS Module TX* *09 to GPS Module RX* *********************/ #include "SoftwareSerial.h" #include "TinyGPS.h" SoftwareSerial mySerial(10, 9); TinyGPS gps; void gpsdump(TinyGPS &gps); void printFloat(double f, int digits = 2); void setup() { // Open serial communications and wait for port to open: Serial.begin(9600); // set the data rate for the SoftwareSerial port mySerial.begin(9600); delay(1000); Serial.println("uBlox Neo 6M"); Serial.print("Testing TinyGPS library v. "); Serial.println(TinyGPS::library_version()); Serial.println("by Mikal Hart"); Serial.println(); Serial.print("Sizeof(gpsobject) = "); Serial.println(sizeof(TinyGPS)); Serial.println(); } void loop() // run over and over { bool newdata = false; unsigned long start = millis(); // Every 5 seconds we print an update while (millis() - start < 5000) { if (mySerial.available()) { char c = mySerial.read(); //Serial.print(c); // uncomment to see raw GPS data if (gps.encode(c)) { newdata = true; break; // uncomment to print new data immediately! } } } if (newdata) { Serial.println("Acquired Data"); Serial.println("-------------"); gpsdump(gps); Serial.println("-------------"); Serial.println(); } } void gpsdump(TinyGPS &gps) { long lat, lon; float flat, flon; unsigned long age, date, time, chars; int year; byte month, day, hour, minute, second, hundredths; unsigned short sentences, failed; gps.get_position(&lat, &lon, &age); Serial.print("Lat/Long(10^-5 deg): "); Serial.print(lat); Serial.print(", "); Serial.print(lon); Serial.print(" Fix age: "); Serial.print(age); Serial.println("ms."); // On Arduino, GPS characters may be lost during lengthy Serial.print() // On Teensy, Serial prints to USB, which has large output buffering and // runs very fast, so it's not necessary to worry about missing 4800 // baud GPS characters. gps.f_get_position(&flat, &flon, &age); Serial.print("Lat/Long(float): "); printFloat(flat, 5); Serial.print(", "); printFloat(flon, 5); Serial.print(" Fix age: "); Serial.print(age); Serial.println("ms."); gps.get_datetime(&date, &time, &age); Serial.print("Date(ddmmyy): "); Serial.print(date); Serial.print(" Time(hhmmsscc): "); Serial.print(time); Serial.print(" Fix age: "); Serial.print(age); Serial.println("ms."); gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age); Serial.print("Date: "); Serial.print(static_cast(month)); Serial.print("/"); Serial.print(static_cast (day)); Serial.print("/"); Serial.print(year); Serial.print(" Time: "); Serial.print(static_cast (hour+8)); Serial.print(":"); //Serial.print("UTC +08:00 Malaysia"); Serial.print(static_cast (minute)); Serial.print(":"); Serial.print(static_cast (second)); Serial.print("."); Serial.print(static_cast (hundredths)); Serial.print(" UTC +08:00 Malaysia"); Serial.print(" Fix age: "); Serial.print(age); Serial.println("ms."); Serial.print("Alt(cm): "); Serial.print(gps.altitude()); Serial.print(" Course(10^-2 deg): "); Serial.print(gps.course()); Serial.print(" Speed(10^-2 knots): "); Serial.println(gps.speed()); Serial.print("Alt(float): "); printFloat(gps.f_altitude()); Serial.print(" Course(float): "); printFloat(gps.f_course()); Serial.println(); Serial.print("Speed(knots): "); printFloat(gps.f_speed_knots()); Serial.print(" (mph): "); printFloat(gps.f_speed_mph()); Serial.print(" (mps): "); printFloat(gps.f_speed_mps()); Serial.print(" (kmph): "); printFloat(gps.f_speed_kmph()); Serial.println(); gps.stats(&chars, &sentences, &failed); Serial.print("Stats: characters: "); Serial.print(chars); Serial.print(" sentences: "); Serial.print(sentences); Serial.print(" failed checksum: "); Serial.println(failed); } void printFloat(double number, int digits) { // Handle negative numbers if (number < 0.0) { Serial.print('-'); number = -number; } // Round correctly so that print(1.999, 2) prints as "2.00" double rounding = 0.5; for (uint8_t i=0; i 0) Serial.print("."); // Extract digits from the remainder one at a time while (digits-- > 0) { remainder *= 10.0; int toPrint = int(remainder); Serial.print(toPrint); remainder -= toPrint; } }
8. 구동
실제 구동 영상입니다.
신호를 받기 시작하면 GPS의 LED 도 깜빡이면서 구동되고 있다는 것을 알 수 있습니다.
Arduino IDE 의 Serial Monitor 에서 아래와 같은 정보가 스크롤 됩니다.
정보를 보면 제대로 GPS 위성과 통신을 하는 것 같습니다.
확실히 베란다 난간에 GPS 안테나를 붙이니 정보를 잘 받네요.
FIN
일상 생활에서 GPS는 필수 기기 입니다.
눈에 보이지 않았던 중간 단계를 확인할 수 있어서 좋았습니다.
Update
"SMA Female - U. FL" 어뎁터가 도착했습니다.
딱 봐도 굵기가 다릅니다.
역시 신호와 전류는 두꺼운게 좋습니다.
커넥터 부분을 비교해 봤어요.
제일 밑에가 부속으로 딸려 있던 안테나, 중간이 잘못 구입한 MHF-3 규격, 윗부분이 새로 구입한 U. FL 규격 사진입니다.
전체 비교샷 입니다.
NEO-6M 에 바로 결속해 봤습니다.
딱 맞습니다. 손톱으로 의도적으로 뜯지 않는 한, 튼튼하게 결속되어 있습니다.
'Hardware' 카테고리의 다른 글
Hardware | SSD1331 96x64 full color OLED 를 사용해보자 (0) | 2017.09.07 |
---|---|
Hardware | FTDI Serial Adapter 를 사용해 보자 (0) | 2017.09.05 |
Hardware | Probe Clip 을 사용해 보자 (0) | 2017.08.28 |
Hardware | Gyroscope GY-521 MPU-6050 을 사용해 보자 (0) | 2017.08.20 |
Hardware | Resistor Network 을 사용해보자 (0) | 2017.08.17 |
1. Microsoft 에서 나온 IDE
Microsoft 에서도 프로그램 IDE 용으로 "Visual Studio Code" 라는 공개 소프트웨어가 있습니다.
저번에 JetBrains 사의 IntelliJ IDEA 를 써 봤으니, 이번에는 Microsoft 꺼를 써보려 합니다.
- http://- http://chocoball.tistory.com/entry/Software-using-IntelliJ-IDEA
2. Visual Studio Code
사용자들이 충실하게 만들어 놓은 Wikipedia 에서 좋은 정보들을 찾습니다.
- https://en.wikipedia.org/wiki/Visual_Studio_Code
파일은 다음 link 에서 다운로드 가능합니다.
- https://code.visualstudio.com/
IntelliJ 처럼 기능상 차이로 유료/무료로 나뉘지는 않고, 그냥 무료 입니다.
자, 사용을 시작해 볼까요?
3. 시작
Windows OS 기본 언어를 일본어로 설정해 놓다 보니, 초기 화면이 일본어가 떴습니다.
지금까지 여러 일본어로 된 어플을 봐 왔지만,
폰트 사용이 가독성 면에서 최고로 괜찮은것 같습니다.
4. IntelliSense
IntelliSense 란, 요즘 IDE 에서 기본적으로 탑재되고 있는 보조기능입니다.
이 기능은, programmer 가 타이핑 하고 있으면, 미리 타이핑 할 것을 예측하여 보여주고,
programmer 는 모든 code 를 타이핑하는 것이 아니라, 보여준 예시에서 선택하여, coding 속도를 높이고 typo 로 인한 debugging 을
줄여주는 역할을 합니다.
- https://en.wikipedia.org/wiki/Intelligent_code_completion
시험삼아 C 파일을 불러들이자, C++ programming 에 관련된 IntelliSense 파일을 다운로드 받으라고 알려줍니다.
관련된 파일을 받고 reload 한 후, 코딩을 해보면, 몇글자 치면 적당한 예시를 보여주게 됩니다.
IntelliJ 에서 너무 충격받아, 이제 IDE 로서는 당연한 기능인것 같습니다.
5. 형상 관리
Project 를 생성시, 형상 관리로부터 가져올 수 있습니다.
Repository URL 을 입력하면 자동으로 다운로드 받고 확인할 수 있습니다.
최종적으로 GitKraken 과 같은 형상 관리 어플과 연동이 되는지는 모르겠습니다.
Repository 에서 clone 하여 가져올 것이냐고 물어보네요.
문제 없이 import 된 것을 확인할 수 있습니다.
6. Java
Java 소스를 열면, Java 프로그래밍에 필요한 보조적인 플러그인 이나 파일을 받으라고 이야기 해 줍니다.
Java 에 대한 Language Support 파일 인스톨을 선택합니다.
외부 링크에서 찾아서 사이트로 가보면 아래 정보가 뜹니다.
Red hat 에서 만들었군요.
Website 에서 인스톨을 실행시키면, 어플 안에서도 동일한 내용이 뜹니다.
Web --> Application 연동이 잘 되어 있습니다.
보조기능 파일 인스톨이 끝난 후, 리로드 하면, 다음과 같이 runtime 이 없다고 뜹니다.
JDK 를 등록해야 겠죠?
File > Preferences > Settings > Search 에서 JDK 를 치면 메뉴가 아나 나옵니다.
오른쪽 pane 에 설정하면 기본 설정을 override 한다고 합니다.
JDK 가 있는 폴더를 등록해 줍니다.
{ "java.home": "C:\Program Files\Java\jdk1.8.0_112" }
정상적으로 등록이 되면 Restart 하라고 나옵니다.
7. Java 에 대한 IntelliSense 의 간단 확인
이제 환경 설정과 필요한 파일이 모두 깔렸으니,
실제로 Java coding 을 해 봅니다.
IntelliJ 에서는 "sout" 이라고 치면 "System.out.println" 이 자동 입력되었습니다.
Visual Studio Code 에서는 "Syst" 까지 쳐야 그 후에 선택할 수 있게 되어 있네요.
의도한 대로 "System.out.println();" 이 자동 타이핑 되었습니다.
다른 기능들도 이정도는 합니다.
8. 간단 총평
인터페이스는 직관적며, 혼란스럽지 않은 메뉴 구성이지만, 아쉬운 부분이 있습니다.
- class 들간의 종속관계나 람다 표현이라는 것 까지는 보여주지 못한다
- 코드를 간략화 할 수 있는 tip 을 보여주지 않는다
- 예시가 IntelliJ 만큼의 퀄리티와 내용을 보여주지 못한다
급하게 사용해야 할 상황이 되거나, 그냥 저냥의 기능 정도로 충분한 개발에는 부족함이 없습니다.
다만, 조금 깊이가 있고, 코딩을 최적화 하는 용도의 IDE 로는 부족함을 느끼게 됩니다.
FIN
프로그래밍을 업으로 삼는다면, 그냥 돈주고 "IntelliJ" 사다 쓰세요.
그냥 IntelliJ 가 갑입니다.
IntelliJ is the RULE !!!
'Software' 카테고리의 다른 글
Software | FFmpeg 를 사용하여 동영상을 회전시켜 보자 (0) | 2017.09.14 |
---|---|
Software | u-blox 의 GPS 어플을 사용해 보자 (0) | 2017.09.05 |
Software | IntelliJ IDEA 를 사용해 보자 (0) | 2017.08.30 |
Software | Google AdSense 가입 및 설정하기 (0) | 2017.04.30 |
Software | apt-get broken 해결 방법 (0) | 2017.04.16 |
1. Java 개발
저는 개발자가 아닙니다.
다만, IT 에서 일하다 보니, 간단한 스크립트나 Python / Perl 가지고 운영에 보탬이 되거나, 자료 작성시 어쩔수 없이 사용하게 됩니다.
프로그래밍은 절대 하지 않을꺼라는 대학교때 다짐을 했건만...
Java 프로그래밍을 배우면서 몇가지 IDE (Integrated Developed Envrionment) 를 사용할 기회가 있었습니다.
워낙 유명한건 Eclipse 겠죠?
Eclipse 사용시에도, 환경설정이 맞지 않으면 한발자욱도 앞으로 나아갈 수 없고
빨리 코딩하고 싶은데 진행할 수 없는 경우가 허다합니다.
특히 Java 는 JDK 도 있어야 하고, 버전도 맞아야 하고, Spring 까지 가면 돌릴 서버도 가리고...
2. IntelliJ
이번엔 IntelliJ 를 사용할 기회를 가지게 되었습니다.
자동으로 코드를 생성해 주는 "Intelligent Code Completion" 기능이 후덜덜 합니다.
- https://en.wikipedia.org/wiki/Intelligent_code_completion
Java 는 여타 언어와 비교해서 코드 타이핑이 많습니다.
IDE 에서 Intelligent Code completion 을 지원하면, debug 뿐만 아니라 물 흐르듯이 코딩을 즐길 수 있습니다.
물론 Eclipse 에서도 지원 합니다만, 그 질과 성능이 완전 다릅니다. 신선한 경험이네요.
4. Download 및 설치
다운로드는 다음 link 에서 받습니다.
사용 용도에 따라서 Ultimate / Community 구분해서 다운로드 받으면 됩니다.
다만, Web 용은 일정 기간 후 사용 license 를 지불해야 하는 Ultimate 를 사용해야 합니다.
사용해 보면 비용이 아깝지 않음을 느낄 수 있습니다.
- https://www.jetbrains.com/idea/
다운로드 받고 설치파일 실행한 화면 입니다.
설치할 장소를 물어보고...
어떤 런처를 사용할 것인지, 파일 확장자 연결을 할 것인지 물어봅니다.
저는 64bit OS 이니 64bit 를 선택하고, 파일 확장자 연결은 안하는 걸로 했습니다.
파일 확장자 연결은 편하기는 하지만, 리소스를 잡아먹는거라 선호하지 않습니다.
생성할 폴더를 보여주고 ...
완료!
5. 시작하기 전에
이미 이전에 IntelliJ 가 설치되어 있다면 설정을 가지고 올 것인지 물어봅니다.
UI theme 를 물어봅니다.
기본으로 할 것인지 "Darcula" 로 할 것인지 물어보는데, 저는 이 부분을 그냥 지나쳐 버려 나중에 따로 설정하였습니다.
당연, 눈의 피로가 덜한 검은색 바탕의 "Dracula" 태마가 추천입니다.
IntelliJ 를 돌리는 기본 플러그인들의 설정입니다.
Swing / Android / Dev Kit 은 사용하지 않으므로 제외했습니다.
Scala 도 사용하지 않고, Vim 도 사용하지 않을 것이므로 설치하지 않는 것으로 놔둡니다.
Linux 에서 vim 은 없어서는 안되지만, 궂이 GUI 환경에서 Vim 을 사용할 이유는 없으니까요.
이제 시작입니다. "Start using IntelliJ IDEA" 를 누르면 되요.
6. 시작 및 기본 설정
이제 시작 되었습니다.
새로 만들건지, 기존 프로젝트에서 가져올 것인지, 아니면 GitHub 등에서 다운로드 할 것인지를 물어봅니다.
GitHub 에서 가져올 것이라면 "Check out from Version Control" 하시면 됩니다.
새로 프로젝트를 만들면 다음과 같은 화면이 나옵니다.
JDK 가 깔려있지 않으면 선택할 수 없으니, JDK 를 다운로드 받습니다.
일단 인스톨 화면을 놔둔 상태에서 Java JDK 를 다운로드 받습니다.
- http://www.oracle.com/technetwork/java/javase/downloads/index.html
다운로드 받은 파일을 인스톨 합니다.
성공리에 JDK 인스톨이 완료 되었네요.
다시 IntelliJ 프로젝트 생성 화면으로 돌아가 JDK 가 설치된 장소를 선택합니다.
주의할 것은 JRE 가 아니라 JDK 폴더를 선택해야 합니다.
제대로 선택하면 No JDK 에서, 다운로드 받은 파일의 버전으로 바뀌게 됩니다.
그리고 Java 프로젝트는 전무 Maven 프레임워크를 사용할 것이므로, "maven-archetype-quickstart" 를 선택해 줍니다.
이제 기본 설정이 끝났으며, 필요한 파일을 다운로드 받습니다.
Maven project 에 필요한 파일들은 자동으로 받을 수 있도록 "Enable Auto-Import" 를 클릭해 놓습니다.
7. 추가 설정
Java Compiler 가 제대로 설정이 안되어 있을껍니다.
최신판이다 보니 Java 9 으로 컴파일러가 지정되어 있을 가능성이 높습니다.
아래 메뉴로 가서, "Target bytecode version" 부분을 JDK 에 맞게 바꾸어 줍니다.
File > Settings > Build, Execution, Deployment > Java Compiler
또한, project 를 생성 후, project 에서 오른쪽 클릭하면 나오는 아래 메뉴에서
Language Level 을 변경해야 합니다.
Java 8의 혁신적인 기능인 Lambda 가 표시되네요. JDK 가 1.8 이므로 8을 선택하였습니다.
마지막으로 theme 를 제대로 "Daracula" 로 선택하였습니다.
File > Settings > Editor > Color Scheme > Scheme > Dracula
8. 이런 저런 기능
클레스를 만들면, 풀다운 메뉴로 Class 인지 Inteface 인지 선택하개 해줍니다.
물 흐르듯 자연스런 생성 방법이네요.
문법으로서 틀린것은 아니지만, 간략하게 할 수 있거나, 최신 버전에서는 생략해도 되는 것들은
따로 알려줍니다.
Override 했을 시에는 상위 클레스와 연관된 부분을 왼쪽에서 윗 화살표로 보여 줍니다.
상위 클레스는 종속된 클레스가 있는 경우, 그 부분을 표시해 줍니다.
(너무 친절해... ㅠㅠ)
GitHub 등과 같이 Version Control repository 에서 소스를 가져올 경우는,
URL 을 카피하고...
"File > New > Project from Version Control > GitHub" 를 선택하면 됩니다.
9. Intelligent Code Completion
그렇습니다. IntelliJ 를 사용해야 하는 최강의 이유가 바로 "Intelligent Code Completion" 이죠.
뭐 기본적인 완성이나 debugging 도 해주지만,
단축 글씨로 코드를 완성해 주기도 합니다.
아래 스샷은 "public static void main" 의 약자인 "psvm" 을 치고 tab 키를 누르면
코드를 완성해 줍니다.
짜잔~~
System.out.println() 도 sout 이라고 치고 tab 키를 누르면 바로 만들어 줘요.
더욱 놀라운 것은 Java 8 부터 사용된 Lambda 표현식으로 변경할 수 있으면,
그걸 알려줍니다.
또한 lambda 로 구성된 문장은 왼쪽에 람다 아이콘으로 표현하여, "이것이 람다여~" 라고 알려줍니다.
10. JetBrains
이런 멋진 프로그램을 만든 회사는 JetBrains 라는 회사.
이틀밖에 사용해 보지 않았지만, 이걸 어떤 사람들이 만들었을까 싶었습니다.
뭐야, 이사람들은 다 영화배우야?
수준이 느껴집니다.
채용 공고를 보니, 인턴쉽도 한국 대리급 이상 연봉이예요. 인턴쉽이라고!
사무실 분위기도 creative 란 이런거야를 보여주는 인테리어 입니다.
몸을 뒹굴뒹굴 하면서 뇌의 시넵스가 막 연결될것 같습니다.
개발에 집중할 수 있고 최적화된 회사네요.
위치가 어딘가 했더니만 체코의 프라하 였습니다. OMG!
Starbucks 를 좋아하는 저로서는 궁금했습니다. 체코의 Starbucks 는 어떨까?
여긴 가야해 !!!
FIN
세상을 살기 좋게 만드는 건 이런게 아닌가 라는 생각에 잠겨 봅니다.
나도 JetBrains 에서 일하고 싶다...
'Software' 카테고리의 다른 글
Software | u-blox 의 GPS 어플을 사용해 보자 (0) | 2017.09.05 |
---|---|
Software | Visual Studio Code 를 사용해 보자 (0) | 2017.09.01 |
Software | Google AdSense 가입 및 설정하기 (0) | 2017.04.30 |
Software | apt-get broken 해결 방법 (0) | 2017.04.16 |
Software | CH341SER driver 최신 업데이트 하기 (0) | 2017.04.16 |