2015.4.30일에 ms와 arduino간의 파트너쉽이 체결되었다. windows 10이 세계 최초로 arduino에 포팅되는 첫번째 운영체제가 될 수 있을 것 같다. 좋은 IDE도 있어서 기대된다. 


출처 : http://blog.arduino.cc/2015/04/30/microsoft-and-arduino-new-partnership/



* windows get started

http://ms-iot.github.io/content/GetStarted.htm


* window remote arduino

http://ms-iot.github.io/content/win10/SetupWRA.htm


* window visual shields

http://ms-iot.github.io/content/win10/SetupWVSA.htm




http://blogs.windows.com/buildingapps/2015/04/29/microsoft-brings-windows-10-to-makers/


Arduino Partnership


* “Arduino Certified” Windows 10 enables developers to make devices that combine the hardware-driving capability of Arduino with the software capabilities of Windows. An example might be a security camera. One could build a camera using Arduino to power the motor controls to tilt/turn the camera and using Universal Windows Platform one can create great UI, connect the camera to the cloud, process the image for motion detection and add facial/voice recognition. The work we have done on Windows 10 is the bridge between the Universal Windows Platform and Arduino hardware. The initial release includes two key capabilities:


* Windows Virtual Shield for Arduino enables developers to tap into the incredible power of Windows 10 devices through wireless protocols. A Lumia 530 contains well over $200-worth of Arduino shield sensors and capabilities, and we’ve made it easy to access all of those sensors and capabilities from an Arduino as if they were standard hardware shields. Imagine being able to create an Arduino project that includes GPS, Web connectivity/parsing, touch display, speech technologies and more. We’re particularly fond of the picture the weather project we’ve created that lets you bring your children’s drawings to life.

With Windows Remote Arduino we’re enabling developers to extend their Universal Windows Application with Arduino commands that execute on a wirelessly-connected Arduino device. It combines the power of Windows 10 device features such as image processing, speech recognition, website parsing, cameras and advanced audio pipelines with the power of physical world interactivity through Arduino. Take a look at our Basic Windows Remote Arduino project to learn how to leverage this technology in your own projects. 


저작자 표시
신고
Posted by 김용환 '김용환'

아두이노와 OpenWRT를 이용해서 아케이드 버튼(https://www.adafruit.com/product/1185, 9.95$)을 누르도록 교육시켜서, 강아지 셀프 사진을 찍게한 사람이 있어서, 공유. 


좋은 정보 : 



코드 펌질.. 




저작자 표시
신고
Posted by 김용환 '김용환'
출처 : 
http://www.kickstarter.com/projects/435742530/udoo-android-linux-arduino-in-a-tiny-single-board



아두이노가 새로워졌다. 그 이름은 UDOO~~

UDOO is a mini PC that could run either Android or Linux, with an Arduino-compatible board embedded.

  • Freescale i.MX 6 ARM Cortex-A9 CPU Dua/Quad core 1GHz
  • Integrated graphics, each processor provides 3 separated accelerators for 2D, OpenGL® ES2.0 3D and OpenVG™
  • Atmel SAM3X8E ARM Cortex-M3 CPU (same as Arduino Due)
  • RAM DDR3 1GB
  • 54 Digital I/O + Analog Input (Arduino-compatible R3 1.0 pinout)
  • HDMI and LVDS + Touch (I2C signals)
  • Ethernet RJ45 (10/100/1000 MBit)
  • WiFi Module 
  • Mini USB and Mini USB OTG (micro with the final release)
  • USB type A (x2) and USB connector (requires a specific wire)
  • Analog Audio and Mic
  • SATA (Only Quad-Core version)
  • Camera connection
  • Micro SD (boot device)
  • Power Supply (5-12V) and External  Battery connector

지금 절찬 판매중.... 주문해야하는 것인가?? 이런 것은 주문해야지...

Congratulations!

You are now an official backer of UDOO: Android Linux Arduino in a tiny single-board computer. Time to tell the world about it!









저작자 표시
신고
Posted by 김용환 '김용환'

 

온도는 쉽게 이해하지만, 습도는 약간 공부를 해야 한다.

위키(http://ko.wikipedia.org/wiki/%EC%8A%B5%EB%8F%84) 에 따르면 다음과 같이 상대습도를 설명하고 있다.

상대습도는, 특정한 온도대기 중에 포함되어 있는 수증기의 압력을 그 온도의 포화 수증기 압력으로 나눈 것을 말한다. 다시 말해, 특정한 온도의 대기 중에 포함되어 있는 수증기의 양(중량 절대습도)을 그 온도의 포화 수증기량(중량 절대습도)으로 나눈 것이다.

상대습도 100%로, 대기 중의 수증기량이 포화되어, 결로 현상을 일으킨다. 또 그때의 온도를 이슬점 온도라고 한다.

 RH = {p_{(H_2O)} \over p^*_{(H_2O)}} \times 100%

 

HIH-4030  센서는 상대습도를 체크하는 센서이기 때문이다. 따라서 수증기의 양과 온도를 가지고 측정하는 센서이다. 생긴 것은 아래와 같이 생겼다.

 

 

습도 센서 HIH-4030은 5V에서 최적화되어 동작한다. 
(http://www.sparkfun.com/datasheets/Sensors/Weather/SEN-09569-HIH-4030-datasheet.pdf)

특별히 저항을 넣지 않고 바로 쓸 수 있다.

image

(http://www.sparkfun.com/datasheets/Sensors/Weather/HIH-4030_Breakout-v10.pdf)

이 센서는 상대 습도 (Relative Humidity %RH)를 측정하고 analog output pin(위의 그림으로 OUT)으로 voltage 값을 던진다. 아두이노에서는 이 analog output pin의 값을 읽어 처리하면 된다.  오차는 +-3.5이다. -40~85 도에서 측정가능하다.

상대습도는 공기 중에 포함되어 있는 수증의 양 또는 비율을 나타낸다. (http://ko.wikipedia.org/wiki/%EC%8A%B5%EB%8F%84) 이 값을 측정하는 법이 hih 4030 datasheet에 잘 나와 있다. (http://www.sparkfun.com/datasheets/Sensors/Weather/SEN-09569-HIH-4030-datasheet.pdf)

 

image

표에 보면, 두가지 값이 나온다.

Voltage output 과 Temperature compensation 이다. 이 공식을 잘 봐둔다.

 

센서의 달인이 아닌 관계로 누군가의 글을 참조해야 했다.

일본사람의 블로그를 참조(http://www.eleki-jack.com/FC/2011/04/arduinohih4030.html) 하여 정리해본다.

 

(첫번째: Voltage output)

Vout =(Vsupply)0.0062(sensorRH) + 0.16)

sensorRH 값을  좌항으로 옮기는 식을 만드면 다음과 같다.

sensorRH =(Vout/Vsupply)×(1/0.0062)- 0.16 ×(1/0.0062)  ---- (1)

Vout/Vsupply (전원대비 출력전압) 에 대해서 1/0.0062 기울기를 가진다고 볼 수 있다.

 

(두번째 : Temperature compensation)

공식를 그대로 적어본다. T 는 섭씨 온도이다. 즉 온도가 필요한 것이다.

RH= sensorRH /(1.0546 - 0.00216 × T)  -- (2)

 

참고로 센서의 출력 전압은 다음 공식이다.

Vout = Vsupply × (아날로그 입력 값 /1024)

다음 식으로 치환이 된다.

Vout / Vsupply = (아날로그 입력 값 / 1024)

 

위의 식을 (1) 식에 적용해 본다.

sensorRH =(Vout/Vsupply)×(1/0.0062)- 0.16 ×(1/0.0062)

Vout / Vsupply = (아날로그 입력 값 / 1024)

 

SensorRH의 값은 다음의 값을 가지게 된다.

SensorRH = (아날로그 입력 값/1024)  X (1/0.0062) – 0.16 X (1/0.0062)

 

테스트를 시작해 본다. 

아래와 같이 셋팅한다.

image

 

코드를 업로드 한다.


float vdd = 5.0;
int indata;
float sRH;

void setup() {
  Serial.begin(9600);
}

void loop() {
  indata = analogRead(0);
  sRH = (indata/1024.0)/0.0062-0.16/0.0062;
  Serial.println(sRH);
  delay(1000);
}

 

Serial Monitor 창을 열어 sensor RH 값을 얻는다.

image

 

이제 진짜 RH를 구해야 할 차례이다.

 

이번에는 온도를 이용해서 다른 식을 구해야 한다. 이번에 습도 센서 공식 2를  다시 작성한다.

sensorRH 값과 T 온도 값을 넣어야 실제 습도를 체크할 수 있다.

RH= sensorRH /(1.0546 - 0.00216 × T) 

 

이미 sensor RH를 구했으니 T만 구하면 된다.

 

온도 센서는 TMP 36을 이용한다.

 

(이미지 : http://www.ladyada.net/learn/sensors/tmp36.html)

 

OUT를 analog port 1로 연결한다.

 

 

이것을 보드에 잘 연결한다.  (선이 개판이긴 하지만..)

image

 

온도 T를 구하기 위해서는 TMP 36 data sheet 과 TMP 36 튜터리얼 을 이용한다.

 

data sheet에 나와 있는 자료를 본다 .(http://www.analog.com/static/imported-files/data_sheets/TMP35_36_37.pdf)

image

The TMP36 is specified from −40°C to +125°C, provides a 750 mV output at 25°C, and operates to 125°C from a single 2.7 V supply. The TMP36 is functionally compatible with the LM50. Both the TMP35 and TMP36 have an output scale factor of 10 mV/°C.

 

그 다음은 튜터리얼(http://www.ladyada.net/learn/sensors/tmp36.html)을 참조했다.

 

먼저 Voltage를 구하고, 섭씨 온도를 구한다.

Voltage at pin in milliVolts = (reading from ADC) * (5V/1024)  ----- (1)

Centigrade temperature = [(analog voltage in mV) – 0.5] / 10 –---- (2)

 

이제 온도 T를 구하는 공식은 다음과 같다.

 

T = ((input * 5 / 1024) – 0.5 ) / 10

 

그렇다면, 위의 T 값을 구하면 RH를 구할 수 있다.


RH= sensorRH /(1.0546 - 0.00216 × T) 

 

이를 코드로 하면 다음과 같다.

 

float vdd = 5.0;
int indata0, indata1;
float sRH;
float RH;
float voltage;
float temperatureC;

void setup() {
  Serial.begin(9600);
}

void loop() {
  indata0 = analogRead(0);
  sRH = (indata0/1024.0)/0.0062-0.16/0.0062;

  indata1 = analogRead(1);
  voltage = indata1*5.0/1024.0;
  temperatureC = (voltage - 0.5) * 100;
  Serial.print(temperatureC); Serial.println(" 'C");
 
  RH=sRH/(1.0546-0.00216*temperatureC);
  Serial.print(RH);
  Serial.println(" RH");
  Serial.println("----");
  delay(1000);
}


온도와 습도 값이 잘 나온다.

image

 

상대 습도이니. 만약 HIH-4030 센서에 입김을 불면 확실히 값이 달라지게 나와야 할 것이다.

지금 온도가 23.73 C 이고, 20.43 습도를 가지고 있는데, 입김을 부니, 온도와 습도의 값이 올라간다.

image

 

 

5초에 한번씩 테스트할 때, 온도 센서인 tmp 36의 상태를 보면, 조금씩 튀는 것이 보인다. 아마도 센서이다 보니 오차가 있을 수 있다. 온도가 바뀌면 자연스럽게 상대 습도에도 영향이 받는다. 그래서 빛&감열 센서를 이용하면 좀더 정확한 값을 얻을 수 있다고 튜터리얼에 적혀 있다. (http://www.ladyada.net/learn/sensors/tmp36.html)

 

아래 그림을 참조했다.

 

온도센서 근처에 빛&감열 센서 와 저항 10k를 달고 analog 3번 input으로 받도록 했다. 그리고, 전원을 aref input으로 넣게 했다. 이렇게  하면 정확한 volt 값을 알 수 있다고 한다. 해봤는데. 크게 차이가 나지 않는다.

 

image

 

상대 습도계는 기본적으로 오차가 거의 없는 좋은 온도 센서가 있어야 습도 값을 구할 수 있다. 그래서 온도계를 잘 만드는 회사가 습도계를 잘 만드는 것 같다. 선물용으로 주는 이름없는 브랜드를 까보니. 온도센서의 값이 100원짜리다.. 온도 센서의 값어치를 잘 알아야 할 것 같다는 생각을 하게 되었다.

 

마치며…

별 것은 없지만, 생각보다 많은 시간이 소요되었다. 센서에 대한 이해라든가, 수치에 대한 이해라든가.. 이 부분에 대해서 깊은 내공이 쌓여야 할 것 같다.

다음은 온도와 습도의 값을 읽어 자바 언어를 이용해서 MRTG로 만들려고 한다. 이를 통해서 내가 있는 곳의온도/습도의 추이를 보려고 하려고 한다.

신고
Posted by 김용환 '김용환'

 

온도는 쉽게 이해하지만, 습도는 약간 공부를 해야 한다.

위키(http://ko.wikipedia.org/wiki/%EC%8A%B5%EB%8F%84) 에 따르면 다음과 같이 상대습도를 설명하고 있다.

상대습도는, 특정한 온도대기 중에 포함되어 있는 수증기의 압력을 그 온도의 포화 수증기 압력으로 나눈 것을 말한다. 다시 말해, 특정한 온도의 대기 중에 포함되어 있는 수증기의 양(중량 절대습도)을 그 온도의 포화 수증기량(중량 절대습도)으로 나눈 것이다.

상대습도 100%로, 대기 중의 수증기량이 포화되어, 결로 현상을 일으킨다. 또 그때의 온도를 이슬점 온도라고 한다.

 RH = {p_{(H_2O)} \over p^*_{(H_2O)}} \times 100%

 

HIH-4030  센서는 상대습도를 체크하는 센서이기 때문이다. 따라서 수증기의 양과 온도를 가지고 측정하는 센서이다. 생긴 것은 아래와 같이 생겼다.

 

 

습도 센서 HIH-4030은 5V에서 최적화되어 동작한다. 
(http://www.sparkfun.com/datasheets/Sensors/Weather/SEN-09569-HIH-4030-datasheet.pdf)

특별히 저항을 넣지 않고 바로 쓸 수 있다.

image

(http://www.sparkfun.com/datasheets/Sensors/Weather/HIH-4030_Breakout-v10.pdf)

이 센서는 상대 습도 (Relative Humidity %RH)를 측정하고 analog output pin(위의 그림으로 OUT)으로 voltage 값을 던진다. 아두이노에서는 이 analog output pin의 값을 읽어 처리하면 된다.  오차는 +-3.5이다. -40~85 도에서 측정가능하다.

상대습도는 공기 중에 포함되어 있는 수증의 양 또는 비율을 나타낸다. (http://ko.wikipedia.org/wiki/%EC%8A%B5%EB%8F%84) 이 값을 측정하는 법이 hih 4030 datasheet에 잘 나와 있다. (http://www.sparkfun.com/datasheets/Sensors/Weather/SEN-09569-HIH-4030-datasheet.pdf)

 

image

표에 보면, 두가지 값이 나온다.

Voltage output 과 Temperature compensation 이다. 이 공식을 잘 봐둔다.

 

센서의 달인이 아닌 관계로 누군가의 글을 참조해야 했다.

일본사람의 블로그를 참조(http://www.eleki-jack.com/FC/2011/04/arduinohih4030.html) 하여 정리해본다.

 

(첫번째: Voltage output)

Vout =(Vsupply)0.0062(sensorRH) + 0.16)

sensorRH 값을  좌항으로 옮기는 식을 만드면 다음과 같다.

sensorRH =(Vout/Vsupply)×(1/0.0062)- 0.16 ×(1/0.0062)  ---- (1)

Vout/Vsupply (전원대비 출력전압) 에 대해서 1/0.0062 기울기를 가진다고 볼 수 있다.

 

(두번째 : Temperature compensation)

공식를 그대로 적어본다. T 는 섭씨 온도이다. 즉 온도가 필요한 것이다.

RH= sensorRH /(1.0546 - 0.00216 × T)  -- (2)

 

참고로 센서의 출력 전압은 다음 공식이다.

Vout = Vsupply × (아날로그 입력 값 /1024)

다음 식으로 치환이 된다.

Vout / Vsupply = (아날로그 입력 값 / 1024)

 

위의 식을 (1) 식에 적용해 본다.

sensorRH =(Vout/Vsupply)×(1/0.0062)- 0.16 ×(1/0.0062)

Vout / Vsupply = (아날로그 입력 값 / 1024)

 

SensorRH의 값은 다음의 값을 가지게 된다.

SensorRH = (아날로그 입력 값/1024)  X (1/0.0062) – 0.16 X (1/0.0062)

 

테스트를 시작해 본다. 

아래와 같이 셋팅한다.

image

 

코드를 업로드 한다.


float vdd = 5.0;
int indata;
float sRH;

void setup() {
  Serial.begin(9600);
}

void loop() {
  indata = analogRead(0);
  sRH = (indata/1024.0)/0.0062-0.16/0.0062;
  Serial.println(sRH);
  delay(1000);
}

 

Serial Monitor 창을 열어 sensor RH 값을 얻는다.

image

 

이제 진짜 RH를 구해야 할 차례이다.

 

이번에는 온도를 이용해서 다른 식을 구해야 한다. 이번에 습도 센서 공식 2를  다시 작성한다.

sensorRH 값과 T 온도 값을 넣어야 실제 습도를 체크할 수 있다.

RH= sensorRH /(1.0546 - 0.00216 × T) 

 

이미 sensor RH를 구했으니 T만 구하면 된다.

 

온도 센서는 TMP 36을 이용한다.

 

(이미지 : http://www.ladyada.net/learn/sensors/tmp36.html)

 

OUT를 analog port 1로 연결한다.

 

 

이것을 보드에 잘 연결한다.  (선이 개판이긴 하지만..)

image

 

온도 T를 구하기 위해서는 TMP 36 data sheet 과 TMP 36 튜터리얼 을 이용한다.

 

data sheet에 나와 있는 자료를 본다 .(http://www.analog.com/static/imported-files/data_sheets/TMP35_36_37.pdf)

image

The TMP36 is specified from −40°C to +125°C, provides a 750 mV output at 25°C, and operates to 125°C from a single 2.7 V supply. The TMP36 is functionally compatible with the LM50. Both the TMP35 and TMP36 have an output scale factor of 10 mV/°C.

 

그 다음은 튜터리얼(http://www.ladyada.net/learn/sensors/tmp36.html)을 참조했다.

 

먼저 Voltage를 구하고, 섭씨 온도를 구한다.

Voltage at pin in milliVolts = (reading from ADC) * (5V/1024)  ----- (1)

Centigrade temperature = [(analog voltage in mV) – 0.5] / 10 –---- (2)

 

이제 온도 T를 구하는 공식은 다음과 같다.

 

T = ((input * 5 / 1024) – 0.5 ) / 10

 

그렇다면, 위의 T 값을 구하면 RH를 구할 수 있다.


RH= sensorRH /(1.0546 - 0.00216 × T) 

 

이를 코드로 하면 다음과 같다.

 

float vdd = 5.0;
int indata0, indata1;
float sRH;
float RH;
float voltage;
float temperatureC;

void setup() {
  Serial.begin(9600);
}

void loop() {
  indata0 = analogRead(0);
  sRH = (indata0/1024.0)/0.0062-0.16/0.0062;

  indata1 = analogRead(1);
  voltage = indata1*5.0/1024.0;
  temperatureC = (voltage - 0.5) * 100;
  Serial.print(temperatureC); Serial.println(" 'C");
 
  RH=sRH/(1.0546-0.00216*temperatureC);
  Serial.print(RH);
  Serial.println(" RH");
  Serial.println("----");
  delay(1000);
}


온도와 습도 값이 잘 나온다.

image

 

상대 습도이니. 만약 HIH-4030 센서에 입김을 불면 확실히 값이 달라지게 나와야 할 것이다.

지금 온도가 23.73 C 이고, 20.43 습도를 가지고 있는데, 입김을 부니, 온도와 습도의 값이 올라간다.

image

 

 

5초에 한번씩 테스트할 때, 온도 센서인 tmp 36의 상태를 보면, 조금씩 튀는 것이 보인다. 아마도 센서이다 보니 오차가 있을 수 있다. 온도가 바뀌면 자연스럽게 상대 습도에도 영향이 받는다. 그래서 빛&감열 센서를 이용하면 좀더 정확한 값을 얻을 수 있다고 튜터리얼에 적혀 있다. (http://www.ladyada.net/learn/sensors/tmp36.html)

 

아래 그림을 참조했다.

 

온도센서 근처에 빛&감열 센서 와 저항 10k를 달고 analog 3번 input으로 받도록 했다. 그리고, 전원을 aref input으로 넣게 했다. 이렇게  하면 정확한 volt 값을 알 수 있다고 한다. 해봤는데. 크게 차이가 나지 않는다.

 

image

 

상대 습도계는 기본적으로 오차가 거의 없는 좋은 온도 센서가 있어야 습도 값을 구할 수 있다. 그래서 온도계를 잘 만드는 회사가 습도계를 잘 만드는 것 같다. 선물용으로 주는 이름없는 브랜드를 까보니. 온도센서의 값이 100원짜리다.. 온도 센서의 값어치를 잘 알아야 할 것 같다는 생각을 하게 되었다.

 

마치며…

별 것은 없지만, 생각보다 많은 시간이 소요되었다. 센서에 대한 이해라든가, 수치에 대한 이해라든가.. 이 부분에 대해서 깊은 내공이 쌓여야 할 것 같다.

다음은 온도와 습도의 값을 읽어 자바 언어를 이용해서 MRTG로 만들려고 한다. 이를 통해서 내가 있는 곳의온도/습도의 추이를 보려고 하려고 한다.

신고
Posted by 김용환 '김용환'

 

아트로봇에서 tmp36을 구매해서 아래 링크를 참조로 해서 회로도를 구성했다.

http://artrobot.co.kr/front/php/product.php?product_no=529&main_cate_no=&display_group=
http://www.ladyada.net/learn/sensors/tmp36.html
http://printk.tistory.com/42
http://www.ladyada.net/learn/sensors/tmp36.html




(이미지 참조 : http://www.ladyada.net/learn/sensors/tmp36.html)

내가 원하는 정보는 섭씨 온도인데, 잘 나온다.

int sensorPin = 0;

void setup() {
Serial.begin(9600);
}

void loop() {
int reading = analogRead(sensorPin); 
float voltage = reading * 5.0 / 1024.0;

float temperatureC = (voltage - 0.5) * 100 ;
Serial.println(temperatureC);
delay(1000);   
  
}

float getVoltage(int pin){
  return (analogRead(pin) * .004882814);
}

 

다만, 이 수식이 전류의 흐름이 불확실해지면 정보는 정확하지 않게 나오는 단점이 있다.

신고
Posted by 김용환 '김용환'

 

<서론>

이클립스에서 아두이노 코딩을 위한 컴파일 작업을 했고, (http://knight76.tistory.com/entry/이클립스eclipse에서-avr-코딩해서-아두이노arduino-로-이미지-업로드하기-1)
이번에는 avrdude를 이용해서 이미지 업로드하는 방법을 소개한다.

 

<본론>

1. AVRDude 설정

프로퍼티 설정으로 가서, c/c++ build / Settings의 Addtiontal Tool in ToolChain을 선택한다.

“AVRDude” 설정에 대해서 check on 한다.

 

AVRDude item을 선택하고, Command 라인에 대한 설정 내용은 다음과 같이 수정한다.

“${COMMAND} -F -V  -P com3  -b 115200  -p m328p -c arduino -C G:\Arduino-package\arduino-1.0\hardware\tools\avr\etc\avrdude.conf  -U flash:w:arduino-test.hex”

 

망치 버튼을 눌러 동작을 시켜본다.

avrdude 툴을 써서 잘 이미지(hex)를 업로드하는 것을 확인할 수 있다.


**** Build of configuration 328P_16MHz for project arduino-test ****

make all
Building target: arduino-test.elf
Invoking: AVR C++ Linker
avr-g++ -s -Os -o"arduino-test.elf"  ./src/main.o  ./ref/CDC.o ./ref/HID.o ./ref/HardwareSerial.o
./ref/IPAddress.o ./ref/Print.o ./ref/Stream.o ./ref/Tone.o ./ref/USBCore.o
./ref/WInterrupts.o ./ref/WMath.o ./ref/WString.o ./ref/new.o ./ref/wiring.o
./ref/wiring_analog.o ./ref/wiring_digital.o ./ref/wiring_pulse.o ./ref/wiring_shift.o    -lm -Wl,-Map,arduino-test.map,--cref -mmcu=atmega328p
Finished building target: arduino-test.elf
 
Create Flash image (ihex format)
avr-objcopy -R .eeprom -O ihex arduino-test.elf  "arduino-test.hex"
Finished building: arduino-test.hex
 
Invoking: Print Size
avr-size --format=avr --mcu=atmega328p arduino-test.elf
AVR Memory Usage
----------------
Device: atmega328p

Program:   20130 bytes (61.4% Full)
(.text + .data + .bootloader)

Data:        544 bytes (26.6% Full)
(.data + .bss + .noinit)


Finished building: sizedummy
 
Invoking: AVRDude
G:\Arduino-package\arduino-1.0\hardware\tools\avr\bin\avrdude -F -V  -P com3  -b 115200  -p m328p -c arduino -C G:\Arduino-package\arduino-1.0\hardware\tools\avr\etc\avrdude.conf  -U flash:w:arduino-test.hex

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e950f
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed
         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "arduino-test.hex"
avrdude: input file arduino-test.hex auto detected as Intel Hex
avrdude: writing flash (20130 bytes):

Writing | ################################################## | 100% 3.23s

avrdude: 20130 bytes of flash written

avrdude done.  Thank you.

Finished building: avrdudedummy
 

**** Build Finished ****

 

이렇게 이클립스에서 사용하거나 따로 컴맨드 창에서 동작시켜도 된다.

>avrdude -P com3  -b 115200 -p m328p -c arduino -C../etc/avrdude.conf -F -e -U flash:w:test.hex

 

이런 설정은 하나하나 확인하면서 테스트했었는데. 그럴 필요가 없다. (소스 분석할 때는 없었는데/ ^^;; 완전 나의 삽질~ ㅎ)

hardware/arduino/boards.txt 파일을 보면 아래 arduino uno에 대한 설정 내용이 있다. 이 것만 잘 참조해도  avrdude 바로 쓸 수 있다.

 

uno.name=Arduino Uno
uno.upload.protocol=arduino
uno.upload.maximum_size=32256
uno.upload.speed=115200
uno.bootloader.low_fuses=0xff
uno.bootloader.high_fuses=0xde
uno.bootloader.extended_fuses=0x05
uno.bootloader.path=optiboot
uno.bootloader.file=optiboot_atmega328.hex
uno.bootloader.unlock_bits=0x3F
uno.bootloader.lock_bits=0x0F
uno.build.mcu=atmega328p
uno.build.f_cpu=16000000L
uno.build.core=arduino
uno.build.variant=standar






<예제 파일 돌려보기>

1. 아두이노 스타일 코딩로 코딩하는 것은 어렵지 않다. 잘 동작된다.

main.cpp


#include <Arduino.h>


void setup() {
   pinMode(13, OUTPUT);
}

void loop() {
   digitalWrite(13, HIGH);   // set the LED on
   delay(1000);              // wait for a second
   digitalWrite(13, LOW);    // set the LED off
   delay(1000);              // wait for a second
}

int main(void) {
 init();

#if defined(USBCON)
 USB.attach();
#endif
 
 setup();
   
 for (;;) {
  loop();
  if (serialEventRun) serialEventRun();
 }
       
 return 0;
}





2. 그냥 코딩도 잘 돌아간다.
(http://www.javiervalcarce.eu/wiki/Program_Arduino_with_AVR-GCC에 있는 예제)

main.cpp


#include <avr/io.h>
#include <util/delay.h>

int main (void)
{
  unsigned char counter;
  DDRB = 0xFF;

  while (1)
    {
      PORTB = 0xFF;

      /* wait (10 * 120000) cycles = wait 1200000 cycles */
      counter = 0;
      while (counter != 50)
 {
   /* wait (30000 x 4) cycles = wait 120000 cycles */
   _delay_loop_2(30000);
   counter++;
 }

      /* set PORTB.2 low */
      PORTB = 0x00;

      /* wait (10 * 120000) cycles = wait 1200000 cycles */
      counter = 0;
      while (counter != 50)
 {
   /* wait (30000 x 4) cycles = wait 120000 cycles */
   _delay_loop_2(30000);
   counter++;
 }
    }

  return 1;
}




<project source>




마치며..

이클립스 환경설정하면서 많은 감을 잡은 것 같다. 조금씩 avr도 공부하면서 펌웨어의 즐거움을 즐겨봐야지..
신고
Posted by 김용환 '김용환'

 

<서론>

아두이노 1.0을 바탕으로 윈도우 OS 이클립스에서 아두이노 (AVR) 코딩할 수 있는 환경을 구축하는 방법을 알아보고자 한다.

 

<본론>

1. 가장 먼저 “아두이노 개발툴(pde)”를 설치한다.

나는 1.0 버전으로 설치했다.

 

2. make

mingw 에서 나온 윈도우용 make 유틸리티를 설치한다.

나는 5.1.5 버전을 사용중이다.

http://sourceforge.net/projects/mingw/files/OldFiles/MinGW%205.1.4/MinGW-5.1.4.exe/download 

custom 지정을 잘한다. make을 반드시 설치 목록에 넣어줘야 한다.

 

설치된 mingw/bin 디렉토리를 path에 추가한다.

mingw32-make.exe 파일을 make.exe 파일로 하나 복사해서 사용한다.

 

정상적으로 동작하는지 확인한다.

 

make 유틸리티가 윈도우 path에 등록되어 있지 않으면 이클립스상에서 컴파일은 되지 않는다.

 

**** Build of configuration 328P_16MHz for project arduino-test ****

make all

Error: Cannot run program "make" (in directory "G:\android\workspace\arduino-test\328P_16MHz"): CreateProcess error=2, ??d?? Æ???; ?; ¼? ¾ø

**** Build Finished ****


3. avr Eclipse 플러그인을 설치한다.

http://avr-eclipse.sourceforge.net/wiki/index.php/Plugin_Download 를 참조한다.
플러그인 update 주소는 다음과 같다.

http://avr-eclipse.sourceforge.net/updatesite

AVREclipseInstallUpdatesiteScreenshot.png

(출처 : http://avr-eclipse.sourceforge.net/wiki/index.php/Plugin_Download)

 

4. Preferneces 설정의 AVR Path를 변경

체인툴의 path를 설정해야 한다.

 

path source는 custom으로 하고 설치된 아두이노의 디렉토리를 지정한다.

 

위치 지정은 다음과 같다.

AVG-GCC : hardware\tools\avr\bin
GNU make : hardware\tools\avr\utils\bin
AVR Header Files : hardware\tools\avr\avr\include
AVRDude : hardware\tools\avr\bin

c/c++ / build item에서 Build all configuration in each project를 check on 한다.

 

5. 프로젝트 환경

먼저  c++ 프로젝트를 생성한다.

 

소스 디렉토리를 생성한다.

 

프로젝트의 properties를 설정한다.  내 꺼는 arduino uno이다. MCU type은 Atmgega328P , clock은 16000000로 지정한다.

 

Properties 중 c/c++ build 설정의 “Manage Configuration” 설정을 선택한다.

 

아래와 같은 팝업창에서 “New”버튼을 선택한다.

 

328P_16MHz 라는 이름으로 새로운 설정을 추가한다.

 

OK 버튼을 누르면, 아까 봤던 팝업창이 뜨는데 Set Avice 버튼을 선택한다. 나머지 설정은 다 지운다.

 

AVR tab를 선택하고, 항목에서 Enable시킨다.

 

C/C++ Build –> Settings 설정에서 Configuration 설정에서 328P_16MHz를 선택한다.

 

Settings 아이템의 Additional Tools in Toolchain에서 아래 두 옵션만 check on 한다. (우선은 컴파일하고 바이너리 이미지까지만 만드는 것까지이다.)
”Generate HEX file for flash memroy”, “Print Size”,

 

Tool Settings 밑의 AVR Compiler /Debugging을 선택하고, 정보를 확인한다.

 

AVR Compiler의 Optimization 설정을 다음과 같이 수정한다. 

-Os, 체크박스를 모두 off, "-ffunction-sections -fdata-sections”을 optimization flag로 설정한다.

 

C/C++ Build/Settings 탭의 Tool Settings/AVR Compiler/Language Standard 화면의 옵션을 모두 check off 한다.

 

AVR Compiler의 Directories 설정의 플러스 아이콘을 선택한다.

 


AVR Compiler 의 Directories에 아래 디렉토리를 추가한다. header 파일과 구현 파일들이다.

"G:\Arduino-package\arduino-1.0\hardware\arduino\cores\arduino" : 아두이노 h 및 cpp

"G:\Arduino-package\arduino-1.0\hardware\arduino\variants\standard" : pins_arduino.h

 

AVR Compiler 처럼 AVR C++ Compiler 부분도 똑같이 수정해야 한다. (사실 cpp로 동작하기 때문에 c++ compiler 설정을 더 잘해야 한다.)

 

AVR C++ Compiler/Debugging 설정을 잘 되었는지 확인한다.

 

Optimization 설정도 똑같이 한다.

 

Language Standard도 똑같이 설정한다.

 

Directories도 동일하게 설정한다.

 

 

6. 링커 설정

AVR C++ Linker에서 다음과 같이 설정한다.

Command는 avr-gcc,

Command line pattern은 “ ${COMMAND} -s -Os ${OUTPUT_FLAG}${OUTPUT_PREFIX}${OUTPUT} ${INPUTS} -lm ${FLAGS}”으로 지정한다. (복사하면서 유니코드가 들어갈 수 있어 빌드 실패가 일어날 수 있음)

 

그리고, Library 설정은 특별히 하지 않는다.

 

7. 아두이노 디렉토리를 import한다.

Import/Filesystem 을 이용해서 Include된 디렉토리를 참조하게 한다. 이 파일들로 인해서 컴파일 시 참조가 되게 한다.

 

 

8. 컴파일

 

main.cpp 파일에 있는 setup(), loop()를 주석을 제거하거나 exmple 소스 하나를 구현해본다.

 

#include <Arduino.h>


void setup() {
      pinMode(13, OUTPUT);
}

void loop() {
      digitalWrite(13, HIGH);   // set the LED on
      delay(1000);              // wait for a second
      digitalWrite(13, LOW);    // set the LED off
      delay(1000);              // wait for a second
}

int main(void)
{
    init();

#if defined(USBCON)
    USB.attach();
#endif
   
    setup();
   
    for (;;) {
        loop();
        if (serialEventRun) serialEventRun();
    }
       
    return 0;
}

 

잘 생각해보면, 아두이노  개발 툴 에서 setup(), loop()를 구현한 코드에서 main.cpp 와 링킹하면서 바이너리가 만들어지는 모델이라는 점을 쉽게 이해할 수 있다.

 

컴파일을 하려면 툴바에 있는 망치를 선택한다.

 

컴파일하면, 다음과 같이 잘 되는지 확인가능 하다. 빌드 과정을 보면서 지금까지 셋팅한 정보로 컴파일되는지 확인한다.


**** Build of configuration 328P_16MHz for project arduino-test ****

make all
Building file: ../src/main.cpp
Invoking: AVR C++ Compiler
avr-g++  -I"G:\Arduino-package\arduino-1.0\hardware\arduino\cores\arduino" -I"G:\Arduino-package\arduino-1.0\hardware\arduino\variants\standard" -Wall -g2 -gstabs -Os -ffunction-sections -fdata-sections -fno-exceptions -mmcu=atmega328p -DF_CPU=1600000UL -MMD -MP -MF"src/main.d" -MT"src/main.d" -c -o "src/main.o" "../src/main.cpp"
Finished building: ../src/main.cpp
 
Building target: arduino-test.elf
Invoking: AVR C++ Linker
avr-g++ -s -Os -o"arduino-test.elf"  ./src/main.o  ./ref/CDC.o ./ref/HID.o ./ref/HardwareSerial.o
./ref/IPAddress.o ./ref/Print.o ./ref/Stream.o ./ref/Tone.o
./ref/USBCore.o ./ref/WInterrupts.o ./ref/WMath.o ./ref/WString.o
./ref/new.o ./ref/wiring.o ./ref/wiring_analog.o ./ref/wiring_digital.o
./ref/wiring_pulse.o ./ref/wiring_shift.o    -lm -Wl,-Map,arduino-test.map,--cref -mmcu=atmega328p
Finished building target: arduino-test.elf
 
Create Flash image (ihex format)
avr-objcopy -R .eeprom -O ihex arduino-test.elf  "arduino-test.hex"
Finished building: arduino-test.hex
 
Invoking: Print Size
avr-size --format=avr --mcu=atmega328p arduino-test.elf
AVR Memory Usage
----------------
Device: atmega328p

Program:   20130 bytes (61.4% Full)
(.text + .data + .bootloader)

Data:        544 bytes (26.6% Full)
(.data + .bss + .noinit)


Finished building: sizedummy
 

**** Build Finished ****

 

Navigator 또는 Project Explorer로 보면, 아래와 같이 make 파일과 hex, elf 파일이 생성되는지 확인할 수 있다.

 

이제는 이미지 업로드하는 작업을 한다.

신고
Posted by 김용환 '김용환'

 

과거에 임베디드 시스템을 개발 및 포팅할 때는 컴파일과 업로드(버닝) 이렇게 두가지를 사용했다. 컴파일할 때는 크로스 컴파일러 쓰고 업로드할 때는 따로 하드웨어 업체(삼성, LG)에서 준 툴을 이용해서 업로드 했다. 이번에 아두이노를 분석해가면서 avrdude 라는 파일을 처음 보게 되어서 공부차 작성해 본다. 

avrdude는 AVR 마이크로 콘트롤러에 ROM과 EEPROM 이미지를 업로드하는 유틸리티이다. “http://www.nongnu.org/avrdude/” URL에 따르면, Braian S. Dean이라는 사람이 AVR 마이크로 시리즈를 위한 in-system 프로그램 프로젝트중의 하나였다고 한다.처음에는 FreeBSD에 포팅했었고 다양한 운영체제서도 동작하기를 원하는 요구사항이 있어서, 싸이트(http://savannah.nongnu.org/projects/avrdude)를 오픈하고 사람들이 접근해서 쓸 수 있도록 하였다.

아두이노 및 다른 ISP칩셉에 연동이 가능하다. 그 이유는 설정파일 (avrdude.conf)을 가지고 할 수 있다.

<http://savannah.nongnu.org/projects/avrdude>

image

 

기능을 알기 위해서 살펴본다.

>avrdude
Usage: avrdude [options]
Options:
  -p <partno>                Required. Specify AVR device.
  -b <baudrate>              Override RS-232 baud rate.
  -B <bitclock>              Specify JTAG/STK500v2 bit clock period (us).
  -C <config-file>           Specify location of configuration file.
  -c <programmer>            Specify programmer type.
  -D                         Disable auto erase for flash memory
  -i <delay>                 ISP Clock Delay [in microseconds]
  -P <port>                  Specify connection port.
  -F                         Override invalid signature check.
  -e                         Perform a chip erase.
  -O                         Perform RC oscillator calibration (see AVR053).
  -U <memtype>:r|w|v:<filename>[:format]
                             Memory operation specification.
                             Multiple -U options are allowed, each request
                             is performed in the order specified.
  -n                         Do not write anything to the device.
  -V                         Do not verify.
  -u                         Disable safemode, default when running from a scrip
t.
  -s                         Silent safemode operation, will not ask you if
                             fuses should be changed back.
  -t                         Enter terminal mode.
  -E <exitspec>[,<exitspec>] List programmer exit specifications.
  -x <extended_param>        Pass <extended_param> to programmer.
  -y                         Count # erase cycles in EEPROM.
  -Y <number>                Initialize erase cycle # in EEPROM.
  -v                         Verbose output. -v -v for more.
  -q                         Quell progress output. -q -q for less.
  -?                         Display this usage.

avrdude version 5.11, URL: <http://savannah.nongnu.org/projects/avrdude/>

 

아두이노 우노에 이미지를 업로드하려면 다음과 같이 사용하는데, 간단히 보면 다음과 같다.

> avrdude -p atmega328p -P com3 -c arduino -U flash:w:gds.hex:i

   
-p atmega328p    마이크로 프로세서의 타입을 지정한다.
-c arduino 통신 프로토콜을 지정한다.
-P com3 com3 시리얼 포트로 내려받는다.
-U flash:w:gds.hex:i

flash 는 flash memory를 의미
w 는 write를 의미
test.hex = 업로드할 파일
I = Intel 의 hex format을 의미

신고
Posted by 김용환 '김용환'

 

C 소스를 가지고 윈도우에 설치된 체인툴을 가지고 크로스 컴파일을 해보려고 시도했다.

 

소스에 가장 먼저 #define 되어야 하는 부분은 AVR 타입에 대한 정보이다. 만약 이 부분을 넣지 않으면 warning과 함께 컴파일이 되지 않는다. avr/include/avr 디렉토리의 io.h 파일에 정의되어 있다.

….

#elif defined (__AVR_ATmega328P__)
#  include <avr/iom328p.h

….

#  if !defined(__COMPILING_AVR_LIBC__)
#    warning "device type not defined"
#  endif
#endi

 

아두이노 우노(arduino uno) 라면 ATmega328 프로세스를 사용하고 있으므로, 다음과 같이 정의해야 한다.
#define __AVR_ATmega328P__

또는 avr-gcc 실행시 –mmcpu 파라미터값에 atmega328p를 추가해야 한다.

 

아주 간단한 소스를 컴파일하고 업로드하는 것을 해본다.

<test.c>

#define __AVR_ATmega328P__
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>

int main() {
  // 셋업
  DDRB = 0xFF;

  while (1) {
    PORTB = 0xFF;
    _delay_loop_2(1000;
    PORTB = 0x00;
    _delay_loop_2(1000);
  }
}

 

avr 칩에서 동작하는 바이너리 파일을 만든다.

> avr-gcc -O test.c -o test.bin

 

.text와 .data 파일이 포함하는 .hex 파일을 만든다.

>avr-objcopy -j .text -j .data -O ihex test.bin test.hex

 

.hex 파일을 가지고 아두이노 uno에 업로드를 하면 된다.  [속도(b옵션) : 115200, 보드이름(p옵션) arduino 가 반드시 맞아야 한다.] 보드이름에 대한 자세한 정보는 avrdude.conf에 기록 되어 있음

>avrdude -P com3  -b 115200 -p m328p -c arduino -C../etc/avrdude.conf -F -e -U flash:w:test.hex


신고
Posted by 김용환 '김용환'

 

아두이노 개발 툴 1.0에 대한 소스 분석 글이다.

http://knight76.tistory.com/entry/아두이노-개발-툴-소스-10-분석을-위한-환경-셋팅 에 이어 소스 분석을 시작한다.  프로세싱 개발 툴과 너무 흡사한 UI를 가졌기 때문에 소스 분석이 조금 더 쉬운 것 같다.

먼저 빌드 순서를 파악하고, 소스를 파악한다. (짜잘한 것은 제외) 그리고 주석이 약간 틀린 부분이 있었다.ㅠ

1. 빌드 순서


(1) build/build.xml

운영체제(플랫폼)에 맞는 빌드 콜을 호출한다. 윈도우의 경우 windows-build target이 가장 먼저 실행이 된다.

    1) todo.txt 파일의 revistion 숫자, processing/app/Base.java 파일의 revision 정보와 비교해서 revision 번호를 맞춘다.

    2) 윈도우 운영체제인지 확인한다.

    3) core 디렉토리와 app 디렉토리에 ant 컴파일을 시킨다.

       -  core/build.xml
           core 디렉토리를 컴파일하고 bin/core.jar 파일을 만든다.

       -  app/build.xml
           app 디렉토리를 컴파일하고, bin/pde.jar 파일을 만든다.

4) windows/work 디렉토리를 생성 후, 실행에 필요한 libraray (jar, dll)과 driver 파일들을 복사한다. 그리고, window/work/hardware 디렉토리에 윈도우에서 동작할 수 있는 avr 툴(avr 체인) 압축 파일을 풀어둔다.

5) windows/work 디렉토리의 여러 디렉토리에 셋팅을 한다.

    1) windows/work/tools 디렉토리에 Mangler.java 소스를 복사한다.

    2) window/work/library 디렉토리에 아두이노 library 파일을 복사한다.

    3) window/work/hardware 디렉토리에  아두이노 부트로더, 펌웨어등을 복사한다.

    3) window/work/example 디렉토리에는 간단히 예제들을 복사해둔다.

6) launch관련 파일들을 모은다. launch4j와 설정파일, 관련 클래스들을 모아둔다.

7) launch4j를 실행하고, 컴파일하고 링킁하고 실행파일(build\windows\work\arduino.exe)을 생성한다.

launch4j를 이용하여 exe 파일을 만드는 config.xml 파일이다.

<launch4jConfig>
  <dontWrapJar>true</dontWrapJar>
  <headerType>gui</headerType>
  <jar>lib</jar>
  <outfile>arduino.exe</outfile>
  <errTitle></errTitle>
  <cmdLine></cmdLine>
  <chdir>.</chdir>
  <priority>normal</priority>
  <downloadUrl>http://java.sun.com/javase/downloads/</downloadUrl>
  <supportUrl></supportUrl>
  <customProcName>false</customProcName>
  <stayAlive>false</stayAlive>
  <manifest></manifest>
  <icon>application.ico</icon>
  <classPath>
   <mainClass>processing.app.Base</mainClass>
    <cp>lib/pde.jar</cp>
    <cp>lib/core.jar</cp>
    <cp>lib/jna.jar</cp>
    <cp>lib/ecj.jar</cp>
    <cp>lib/RXTXcomm.jar</cp>

  </classPath>
  <jre>
    <path>java</path>
    <minVersion>1.5.0</minVersion>
    <maxVersion></maxVersion>
    <jdkPreference>preferJre</jdkPreference>
    <opt>-Xms128m -Xmx128m</opt>
  </jre>
  <splash>
    <file>about.bmp</file>
    <waitForWindow>true</waitForWindow>
    <timeout>60</timeout>
    <timeoutErr>true</timeoutErr>

  </splash>
  <messages>
    <startupErr>An error occurred while starting the application.</startupErr>
    <bundledJreErr>This application was configured to use a bundled Java Runtime Environment but the runtime is missing or corrupted.</bundledJreErr>
    <jreVersionErr>This application requires at least Java Development Kit</jreVersionErr>
    <launcherErr>The registry refers to a nonexistent Java Development Kit  installation or the runtime is corrupted.</launcherErr>
    <instanceAlreadyExistsMsg>An application instance is already running.</instanceAlreadyExistsMsg>
  </messages>
</launch4jConfig>

 

2. UI (Editor)

processing.app.Base.java 소스에 main 메서드를 따라가 본다.

OS(플랫폼)을 확인하고, preferences.txt 프로퍼티 화일(크기..)을 읽는다. theme/theme.txt 프로퍼티 설정을 읽어 editor에 대한 프로퍼티를 확인한다. look&feel 을 설정후, 임시폴더를 만들고 Base 객체를 생성한다.

Base 생성자 코드를 따라가면, examples, libraries, tools 디렉토리 패스와 프로젝트 파일로 저장할 path (sketchbook path) 를 지정해둔다. hardware 디렉토리를 잘 기억한다. Editor 클래스를 초기화하여 UI를 실행한다. 이전에 아두이노 개발 툴을 종료했을 때 사용했던 스케치 파일이 있었으면 툴 실행시 스케치 파일을 열어둔다.

UI에 관련된 대부분의 특징은 프로세싱 개발 툴과 흡사하다. processing.app 패키지 밑에 잘 들어가 있다.

운영체제에 맞는 특징에 대해서는 운영체제별로 Platform.java 소스에 dependant한 코드들이 들어가 있다. 재미있는 것은 아두이노 오픈 소스 개발자가 macosx 쪽에 Think Different 클래스를 추가했다. 오픈소스의 센스라고 해야 하나 ㅎㅎ 먼가 대단하다고 생각한 코드는 아니지만 웃음코드에 박수~

public class Platform extends processing.app.Platform {

….

public void init(Base base) {
  System.setProperty("apple.laf.useScreenMenuBar", "true");
ThinkDifferent.init(base);
  ..

}

 

public class ThinkDifferent implements ApplicationListener {

… OS X application 이벤트 (open, about 등등)에 대해서 처리하려고 만들었다.

}

아두이노 개발 툴을 UI 초기화하고 menu를 생성하고 editor를 만들면서.. serial port 정보와 타겟 보드가 나와있는데, 이는 processing.app.EditorLineStatus.java 클래스에서 설정 파일을 읽어오는 코드로 동작하게 되어 있다.

맨 처음 읽을 때는 preference.txt 파일에 있는 설정 정보를 읽는다. 이전에 Serial 포트 변경이 있을 때마다 설정값을 변경시키도록 되어 있따.

# ARDUINO PREFERENCES
board = uno
target = arduino

serial.port=COM1

 

3. 아두이노 개발 툴의 스케치 파일 읽고 쓰기

파일을 읽는 시퀀스는 그냥 평범하다.

EditorHeader.rebuildMenu() –> SkechCode.load() –> Base.loadFile() –> PApplet.loadStrings() –>PApplet.createInput() 로 이어져 있다. 파일을 line을 seperator로 String[](내부적으로는 BufferedReader(FileInputStream)클래스를 사용)타입으로 간단하게 파일을 일고, PApplet.join() 메서드에서 String[]에 line separator를 넣어서 String 객체로 리턴한다.

파일을 쓰는 구조는 추측할 수 있도록 파일을 읽는 반대로 구성되어 있다.

 

4. Sketch 파일

아두이노 개발 툴에서 저장하는 파일들을 스케치(Sketch) 라고 한다. 무엇인가를 그리고 거기에 맞게 그린다는 차원에서는 좋아 보이는 개념인 것 같다. processing.app.Sketch.java 클래스는 pde, java 확장자를 지원하고 cpp를 지원하지 않는다. 또한 여러 버그로 인한 많은 땜질 코드들이 보인다. 

processing.app.SketchCode.java 클래스는 코드 자체를 의미하는 클래스로서, 코드가 읽고, 쓰고, 변경될 때 사용되는 클래스이다.

 

 

5. Compile

빌드 Call stack은 다음과 같다.

에디터에서 빌드메뉴를 선택하면, Editor.buildSketchMenu() –>Editor.handleRun()->Editor.presentHandler()
->Thread인 headerListFromIncludePath.run() –> Sketch.build() 로 진행한다.

 

   (1) 전처리 (preprocessor)

컴파일을 하기 전에 전처리(preprocess) 과정을 거친다. Sketch.preprocess() , PdePreprocessor.preprocess()을 참조한다. 소스에 맨 끝에는 \n과 멀티 라인으로 된 주석은 정리되도록 했다. OOME 나 NPE가 발생한 적이 있는 듯 하다. unicode 설정에 되어 있으면 소스를 unicode로 바꾼다.

pde 나 ino 확장자는 가진 파일들은 include 헤더 파일 스트링을 찾아서 저장해 둔다. 소스에서 컴파일과 관련없이 주석, 전처리 지시자, 싱글/더블 따옴표를 모두 스페이스로 만들어버리고 함수 이외 지역에 사용했던 top level brace를 뺀다.  include header 와 정리된 prototype의 line수를 저장해서 나중에 소스를 만들 때 이용한다.

C++ 클래스를 하나 만들어 pde/ino파일에서 사용했던 include 헤더 파일과 #include “Arduino.h”를 추가하고, 잘 정리한 prototype을 넣은 후 cpp 파일로 만들고 컴파일 한다.

 

  (2) 컴파일

Compiler.compile() 메서드에서 정의하고 있는 컴파일러는 avr-gcc (호스트환경은 윈도우이지만, 타겟보드에서 실행할 수 있도록 cross 컴파일을 지원하는 컴파일러) 를 사용하고 있다.  avr base path는 hardware/tools/avr/bin/ 디렉토리를 기준으로 한다.

보드(아두이노 우노)에 맞는 core 라이브러리들이 참조될 수 있도록 라이브러리(hardware\arduino\cores\arduino 디렉토리 밑에 있는 h, cpp 파일들) 들을 잘 정리해둔다.  sketch 파일을 찾아 리스트에 추가하고 컴파일한다.   variants도 필요하면 path에 추가해준다.

    1) 스케치 파일 컴파일

    --- path 디렉토리에 s 확장자로 끝나는 파일을 컴파일

command 창에서 동작할 수 있도록 명령어를 조합하고 object 파일을 만들기 위해서 gcc 컴파일을 실행한다.

    avr-gcc –c –g -assembler-with-cpp -mmcu={$mcu} -DF_CPU={$cpu} -DARDUINO={$number}  –I{IncludePath} {$source file} –o {$object name}

    --- path 디렉토리에 c 확장자로 끝나는 파일을 컴파일

avr-gcc –c –g –Os –Wall –ffunction-section –fdata-section -mmcu={$mcu} -DF_CPU={$cpu} –MMD -DARDUINO={$number}  –I{IncludePath} {$source file} –o {$object name}

    --- path 디렉토리에 cpp 확장자로 끝나는 파일을 컴파일

avr-gcc –c –g –Os –Wall -fno-exceptions –ffunction-section –fdata-section -mmcu={$mcu} -DF_CPU={$cpu} –MMD -DARDUINO={$number}  –I{IncludePath} {$source file} –o {$object name}

 

     2) 라이브러리 컴파일

아두이노 개발 툴에서 짠 소스에서의 include 헤더에 대한 정보들을 모아 관련 디렉토리에서 컴파일한다. 컴파일 하는 방법은 s, c, cpp 확장자로 끝나는 파일로 위의 컴파일 방법과 같다.

    3) 코어 파일 컴파일

cores 디렉토리 밑에 있는 파일들을 찾아 컴파일하고 core.a 파일로 만든다.

avr-ar rcs core.a  파일들

     4) 링킹

avr-gcc –Os -Wl,--gc-sections -mmcu=atmega328p –o  {$primaryclass}.elf  {$objectfile} core.a –L{$buildpath} –lm

     5) EEPROM data 를 만들기

avr-objcopy –O –R  ihex  -j .eeprom --set-section-flags=.eeprom=alloc,load  --no-change-warnings  --change-section-lma .eeprom=0 {$primaryclass}.elf  {$primaryclass}.eep

     6) .hex 파일 만들기

avr-objcopy –O –R  ihex  .eeprom {$primaryclass}.elf  {$primaryclass}.eep

 

 

(3)  보드에 이미지 업로드

EEPROM data를 잘 구워 아두이노 보드에 넣는(upload) 작업을 할 때, processing.app.Upload 클래스, AvrdudeUploader 클래스를 사용한다. 부트 로더를 굽거나 (burn bootlaoder) 할 떄도 사용된다.

Sketch.upload() –> AvrdudeUploader.uploadUsingPreferences() –>AvrdudeUploader.avrdude() 를 호출하는 구조로 되어 있으며, avrdude 라는 명령어를 이용해서 플래쉬에 hex 파일을 굽는다. (-Uflash:w:파일.hex:i’ )

 아두이노의 부트로더를 굽는 방법은 avrdude 명령어에 -Uefuse:w:~~~ 옵션을 넣는다. 

통신방법은 여러가지가 있다. 아마도 운영체제 때문으로 생각된다. 만약 -Pusb 파라미터를 주어서 usb로 통신할 수 있으며, -P {serial port 번호 } 파라미터를 주어서 serial port로 통신할수도 있다.

-b 파라미터로 굽는 속도를 조절할 수 있다. 
 


그리고, Serial 객체를 생성해서 통신하도록 되어 있다.
Serial 클래스는 내부적으로 gnu.io 패키지의 포트 정보를 확인하는 CommPortIdentifier 클래스를 사용하고 있으며, MessageConsumer에 대한 리스너 등록, 이벤트 발생, 데이터를 읽는 형태를 가지고 있다.

 

(4) 윈도우 사용시 레지스트리 이용 - jna

처음 시작할 때, 윈도우에서 ino, pde 파일을 더블 클릭했을 때 아두이노.exe 파일을 실행시키기 위해서, 윈도우 레지스트리에 추가된다. 관련 파일은 Platform.checkAssociations(), Registry 클래스, Advapi32 클래스이다. 여기서도 processing처럼 jna를 아주 잘 쓰고 있다.

public interface Advapi32  extends StdCallLibrary  {

Advapi32 INSTANCE = (Advapi32) Native.loadLibrary("Advapi32", Advapi32.class, Options.UNICODE_OPTIONS);
..
}

 

이상 끝.. 자바로 만들어져서 소스가 어렵지 않다.


참고...
아두이노 개발 툴 없이 소스와 툴만 가지고 컴파일할 때 사용하는 방법은 다음과 같다. 소스에서 사용하는 컴파일 방법과 동일하다.

http://andrew-j-norman.blogspot.com/2011/12/bypassing-ide.html

신고
Posted by 김용환 '김용환'