블로그 검색
AVR 명령어 검색
전자부품 검색

가상 시리얼 포트 에뮬레이터(VSPE)를 이용한 원격간 시리얼포트 제어에 대한 문의가 있어서 답변겸 자료를 정리합니다.

Virtual Serial Ports Emulator(VSPE) 이라는 프로그램을 이용합니다.
설정은 아래와 같습니다.
처음 두줄(Com2)은 제어할 장치가 있는쪽에 설정합니다.
물리적인 com포트에 장치가 물려있다면 첫번째줄은 필요 없습니다.
두번째 줄에서 설정한 포트(자신의 com포트에 맞춤니다)와 그 컴퓨터의 IP를 확인해야 합니다.
(IP확인: 시작> 실행> cmd(엔터) , ipconfig(엔터)

세번째 줄과 네번째 줄은 원격지에서 데이터를 보낼pc에 설정합니다.
거기에도 물리적인 com포트를 쓴다면 세번째는 생략합니다.
네번째에서 서버pc의 IP와 포트로 설정을 합니다.

설정이 모두 끝났습니다.
이제 양방향으로 데이터가 오고 갑니다 확인해보세요.
터미널 프로그램에서 com2 한개 띄우고, com3 한개 띄우면 서로 데이터가 오고 가는것을 확인할수 있습니다.


저는 한pc에서 테스트 하느라 서버와 클라이언트를 위에서 처럼 모두 설정했습니다.
실제로는 위에 두줄은 서버 pc에 아래 두줄은 클라이언트 pc에 설정 하셔야 합니다.
그럼 재미있게 활용하세요 ^^
Posted by pepsiman
comments powered by Disqus
아두이노를 하다보니 좀 이상한 습관이 생겼는데...
전자제품을 그냥 못버린다는 것입니다. ^^
버리기 전에 일단 열어서 머 쓸만한거 없나 확인하게 되죠.
남들이 보면 좀 괘상하게 볼수도 있습니다. ㅎㅎㅎ

얼마전에 복합기(프린터+스캐너)를 하나 발견하고 집으로 가져갔습니다.
아파트 재활용수거날 그렇게 찾아도 못찾았는데 회사앞에서 발견하고
고생(쪽팔림을 무릅쓰고)해서 집까지 운반했내요. ^^

작동하는지에는 별관심이 없었습니다. 오르지 안에있는 모터에만....

헤더부분을 들어났더니 용지 공급하는 스텝모터와 헤더를 이동시키는 (일반)모터가 들어 있네요.
아마도 해더 부분에서 헤더 축에 연결된 투명 띄에서 위치 이동을 인식하는 센서가 들어 있는듯합니다.

새워놓은 모습입니다.

뒷부분에 헤더 이동을위한 모터가 보입니다.

오른쪽 하단의 기어 박스에 들어 있던 스텝모터인데 용도는 잘 모르겠네요.

왼쪽 것이 헤더에 들어 있던 기판이고, 두번째것이 기어박스에 기어의 움직임을 감지하던 센서로 보이는 부품입니다.
오른쪽은 전원부이고요. 이 전원부도 써먹을수 있을까요?

상판 스캐너 부분입니다. 오른쪽에 스텝모터가 보이네요.

이렇게해서 목적이었던 스텝모터 3개를 얻었네요 ㅎㅎㅎ
이상 분해기였습니다. ^^;;

Posted by pepsiman
comments powered by Disqus
전에 구입했던 WIZ811MJ 모듈을 써먹어보려고 하다보니 느러져 있는 선들이 불편해서
간단하게나마 쉴드처럼 만들어보기로 했습니다.
2009/06/08 - 아두이노를 인터넷에 연결해보자 - arduino ethernet shield 호환모듈 WIZ811MJ
2009/05/19 - arduino에 사용가능한 이더넷 모듈

배선만 핀에 맞추어 연결해주면 되기 때문에 최소한의 만능기판과 핀헤더만으로 만들었습니다.
그래서 모양새는 좀 허접합니다. ^^;;;

바깥쪽은 아두이노에 꽂을 핀, 안쪽은 WIZ811MJ에 꽂을 핀헤더 입니다.

만능기판이 양면이 아니라서 핀헤더도 저렇게 연결했네요.

와이어가 겹치면 납땜하다 겹치는 부분이 자꾸 쇼트가 나네요.
동작을 안해서 테스터기로 확인해보면 어김없이 쇼트가 있더군요. 그래서 저 모냥이 됐습니다.
피복이 생각보다 잘 녹나봐요.

저렇게 합체가 되고요.




합체전...

최종 아두이노에 합체한 사진입니다.



요렇게 합체를 해놓고 전원과 랜선을 연결해주면 인터넷으로 접근이 가능합니다.

아무래도 에칭을 못하다보니 만능기판을 자주 사용하게 되네요. 만능기판은 홀위치가 정해저있어 위치가 않맞을 경우도 종종있지만 그냥 쓰고 있습니다. ^^;
만능기판옥션에서 여러가지 팔더군요. 저는 특히 휘어지는 것들이 맘에 들던데...
가격이 그리 만만치는 않지요 ^^;;;

자 이제 무슨 프로그램을 올려볼까요? ^^


Posted by pepsiman
comments powered by Disqus
하기 싫은 일....어쩔수 없이 해야 하는걸까?
재미있으면 하지 말래도 할텐데...
어떻게 하면 강제로 시키지 않고 자발적인 참여를 유도 할 수 있을까?
다음 동영상에서 그 답을 찾아봅니다.





 
아두이노와 직접적인 상관은 없습니다만 아두이노로 저런것을 만들어 보고 싶네요.
개인적으로 첫번째 작품이 맘에 드네요. 해보고 싶어요 ^^

Posted by pepsiman
comments powered by Disqus
와이프가 면 삶을때 시계보고 맞추기 불편하다고 해서 요리할때 사용할수 있는 타이머를 만들어봤습니다.
시간이 정확하진 않겠지만 그리 중요하지 않으니 무시했습니다 ^^;

동작은 SW2 버튼으로 시간을 설정하고 SW1 버튼을 누르면 시계가 거꾸로 가고, 시간이 0이 되면 알람이 울리는 것입니다.

부품도 몇 가지 안됩니다. 
ATTiny26L, 스피커, 스위치 두개, 풀업저항두개, 가변저항 10k ohm, LCD 입니다.

동작시키면 시간(분:초)과 현재 상태를 표시 했습니다.

전원을 9v 배터리로 사용하기 위해 레귤레이터를 이용하여 5v로 다운 하였습니다.



주방에서 사용하기 위해 케이스를 만들었습니다만....
상당히 엉성하네요. ㅠㅠ
어떻게 깔끔하게좀 안될까요?

브레드보드에 있던 회로는 만능기판으로 옮겼습니다.

역시나 이번에도 회로가 막판에 바뀌는 바람에(핑계ㅡㅡ;) 좀 보기 흉합니다. ^^;

SW1 : Start/Stop/time Reset
SW2 : +30 sec

1번 스위치를 한번 누르면 시계가 동작하고 다시 한번 누르면 멈추면서 원래 설정한 시간으로 돌아옵니다.
1번 스위치를 길게 누르면 시간이 0으로 리셋됩니다.

2번 스위치를 한번 누를때마다 설정시간이 30초씩 증가합니다.

옆에 있는 전원 스위치를 없에고 싶었으나 sleep모드를 어떻게 쓰는건지 몰라 포기하고 다음으로 미루었습니다.

작업중 가장 어려웠던 점은 tiny칩의 메모리가 너무 적다는것입니다.
아래 소스보면 아시겠지만 몇줄 안되는데 메모리를 100% 다 사용하더군요.
그래서 소스를 이리 바꾸고 저리 바꾸고 해서 겨우 구겨넣었습니다.
기능을 더 넣고 싶어도 생략하고 최대한 간단하게 넣었습니다.

별건 아니지만 써먹을수 있는걸 만들었다고 생각하니 흐뭇하군요.
얼마나 유용하게 써먹어 줄지는 미지수지만요. ㅎㅎㅎ

$regfile = "attiny26.dat"
$crystal = 4000000
'$sim
$hwstack = 32                                       ' default use 32 for the hardware stack
$swstack = 10                                       ' default use 10 for the SW stack
$framesize = 40                                     ' default use 40 for the frame space

Dim Lsec0 As Long , Lsec1 As Long , Lsec2 As Long , Ltmp As Long , Lmin As Long
Dim Startcooktimer As Byte , Presstime As Long , J As Byte
Dim Idletime As Long

Config Lcdpin = Pin , Db4 = Porta.3 , Db5 = Porta.2 , Db6 = Porta.1 , Db7 = Porta.0 , E = Porta.6 , Rs = Porta.7
Config Portb = Input

Initlcd
Cls
Cursor Off

'Locate 1 , 1 : Lcd "Cooking"
'Locate 2 , 2 : Lcd "Timer"
'Waitms 1000

Lsec0 = 120

Main:
   Startcooktimer = 0
   Gosub Initcooktimer

   Do
      ' SW 6 : Start/Stop/Reset
      If Pinb.6 = 1 Then
         Waitms 20
         If Pinb.6 = 1 And Lsec0 > 0 Then
            Waitms 200
            If Pinb.6 = 0 Then
               Startcooktimer = 1
               Exit Do
            End If
            Waitms 400
            If Pinb.6 = 0 Then
               Startcooktimer = 1
               Exit Do
            End If
            Waitms 400
            ' Reset
            If Pinb.6 = 1 Then
               Lsec0 = 0
               Gosub Initcooktimer
               Waitms 500
            End If
         End If
      End If
      ' SW 5 : +30 sec
      If Pinb.5 = 1 Then
         Waitms 20
         If Pinb.5 = 1 Then
            Lsec0 = Lsec0 + 30
            If Lsec0 >= 60000 Then
               Lsec0 = 0
            End If
            Gosub Initcooktimer
            Waitms 400
         End If
         'Idletime = 0
      End If
   Loop Until Startcooktimer = 1

   'run timer
   Do
      Decr Lsec1
      Gosub Displaycooktimer

      For J = 1 To 20
         If Pinb.6 = 1 Then
            Waitms 20
            If Pinb.6 = 1 Then
               Do
               Loop Until Pinb.6 = 0
               Startcooktimer = 0
               Gosub Initcooktimer
            End If
         End If
         Waitms 50
      Next J

      If Lsec1 <= 0 Then
         Gosub Playsound
         Exit Do
      End If
   Loop Until Startcooktimer = 0
Goto Main

Playsound:
   Sound Portb.4 , 80 , 500
   Waitms 100
   Sound Portb.4 , 80 , 600
   Waitms 100
   Sound Portb.4 , 80 , 700
   Waitms 500

   If Pinb.6 = 1 Then
      Waitms 20
      If Pinb.6 = 1then
         Do
         Loop Until Pinb.6 = 0
         Return
      End If
   End If
   If Pinb.5 = 1 Then
      Waitms 20
      If Pinb.5 = 1 Then
         Do
         Loop Until Pinb.5 = 0
         Return
      End If
   End If
   Goto Playsound
Return

Initcooktimer:
   Lsec1 = Lsec0
   Gosub Displaycooktimer
Return

Displaycooktimer:
   Cls
   Lmin = Lsec1 / 60
   Ltmp = Lmin * 60
   Lsec2 = Lsec1 - Ltmp
   Locate 1 , 1 : Lcd Lmin
   Locate 1 , 3 : Lcd ":"
   Locate 1 , 5 : Lcd Lsec2
   If Startcooktimer = 1 Then
      Locate 2 , 1 : Lcd "Start"
   Else
      Locate 2 , 1 : Lcd "Stop "
   End If
Return



Posted by pepsiman
comments powered by Disqus
재미있는 프로그램을 소개해드립니다.

avr 프로그램을 하다보니 pc와 시리얼 통신을 할일이 종종 생깁니다.

이때 pc용 프로그램을 테스트할때 (특히 노트북 같이 시리얼포트가 없는 pc) 사용하면 편리한 프로그램입니다.

사용법은 가상 COM1, COM2를 만들고 둘을 연결합니다.
pc용 프로그램을 com1로 연결하고 하이퍼 터미널을 com2로 연결하면 pc용 프로그램에서 시리얼 통신으로 출력되는 내용을 하이퍼 터미널에서 확인할수 있습니다.



---------------------------------------------------------------------------------------------------------


일반적인 경우에는 필요 없을지도  모르겠는데, 개발이나 테스트를 하시는 분이라면 꼭 필요한 프로그램입니다.

가상으로 시리얼 포트를 만들어주고 가상 시리얼끼리 리다이렉션도 해줍니다.

가상 시리얼 포트 Com1 Com2를 생성하고 둘을 연결시킨 화면입니다.

이렇게 하면 하이퍼터미널 두개로 Com1과 Com2를 각각 열면 둘간에 통신이 가능하게 됩니다.

시리얼 통신 프로그램 작성하시는 분들께는 대단히 편리한 프로그램이고 게다가 무료입니다.^^

나머지 활용은 어떤게 있을까요? 
Posted by pepsiman
comments powered by Disqus
- 5V와 3.3V 같이 사용하기

아두이노나 atmega128같은 AVR은 주로 5v에서 구동이 됩니다.

하지만 xBee(지그비)나 wiz811mj 같이 3.3v에서 구동되는 모듈들을 사용할 일이 종종 생깁니다.

이럴때 5v를 3.3v로 다운하여 사용하여야 하는데 이같이 전압을 변경하는 방법이 몇가지 있습니다.


1. 레귤레이터(regulator) 사용하기

제일 쉬운 방법은 레귤레이터를 사용하는 방법입니다.

전압 다운
5v 레귤레이터로는 78T05, 3.3v 레귤레이터로는 KA78R33, LM1117S-3.3 등이 있습니다.

위 이미지는 7805를 이용하여 8~18v로 5v를 얻는 방법입니다.
같은 방법으로 3.3v 레귤레이터를 사용하면 3.3v를 얻을 수 있습니다.

전압 업

7805와 위 공식으로 저항을 조절하면 입력보다 높은 전압을 얻을 수 있다네요.




2. 제너 다이오드(zener diode) 사용방법



제너 다이오드 1N4728로 3.3v를 만들고 저항으로 필요 전류를 조절하면 됩니다
저항을 줄이면 전류가 늘어나게 됩니다.


3. 레벨 변환칩 사용

이 방법은 아직 잘 모르겠습니다 ^^;


4. 전압나눔 을 이용한 방법

이 방법은 입력전압이 변하면 출력 전압도 변하므로 안정된 전압은 얻을수 없다는 문제가 있습니다.
Posted by pepsiman
comments powered by Disqus
써미스터는 작고 싸서 정확한 온도가 필요치 않는 곳에 사용하기 그만입니다.
250원짜리로 온도를 측정할수 있다니...정말 저렴하고 매력적인 센서네요.

아두이노를 이용하면 간단한 회로로 가능하니 한번 해보시기 바랍니다.
하지만 써미스터는 온도가 저항값으로 출력되기 때문에 계산하기가 번거롭네요.




NTC_502F397F.xls

엑셀파일에 5도씨 간격으로 온도별 저항값이 적혀 있습니다. 그것을 그래프로 그린것이 위 그래프입니다.

보통 씨피유 파워가 약하거나 시간이 오래 걸리는 계산에는 미리 계산된 값을 배열에 담아서 사용하기도 합니다만
위 엑셀에는 5도씨 간격인것도 있고 세세히 모두 배열에 넣으면 메모리를 많이 차지 한다는 단점도 있습니다.
각자에 상황에 맞게 이용하시면 됩니다.

저는 계산식을 이용해서 프로그램했습니다.
부품 : NTC-502F397
저항= 5K +-1%,  B=3970,    열방산정수= 3.5mW/C

R =R0 exp (B/T-T0)
R0:온도 T0(K)의 저항값 K는 273.15
R :온도 T(K)의 저항값
B :Thermistor 정수
라는데 위 식으론 어떻게 계산하는건지 도무지 계산이 안돼네요 ㅜㅜ  아시는분 계시면 도와주세요.



디바이스마트의 댓글에 적혀 있는 방정식을 토대로 온도를 구했습니다.
T(단위 K) = log(4R -3000) / ( -0.024119329) + 473    --- 저항의 단위는 (옴)
화씨(F) = 1.8 * 섭씨(Tc)+ 32
섭씨(Tc) = (F-32)/1.8
섭씨(Tc) = 절대온도(T) - 273.15

여기서 또 이상한점이 결과가 켈빈 온도라고 되어 있는데 화씨로 계산하니 값이 맞는거 같습니다. ^^;

회로는 써미스터의 출력값이 저항값이기 때문에 전압 나눔회로를 만들어서 저항을 측정했습니다.
기준 저항은 10K옴 입니다.
측정은 아두이노 0번 아날로그핀으로 했습니다.

int analPin = 0;
int ledPin = 13;   // select the pin for the LED
int val = 0;       // variable to store the value coming from the sensor
long x=0, vcc=4840;
float th=0,ce=0;

void setup() {
  pinMode(ledPin, OUTPUT);  // declare the ledPin as an OUTPUT
  Serial.begin(9600);
}

void loop() {
  val = analogRead(analPin);    // read the value from the sensor
  digitalWrite(ledPin, HIGH);  // turn the ledPin on
  x = map(val,0,1023,0,vcc);
  th = (((float)(vcc-x)*10.0)/(float)x)*1000.0;
  ce = ((log(4.0*th - 3000.0) / (-0.024119329) + 473)-32.0)/1.8;
  
  //Serial.print(vcc-x);
  //Serial.print(", ");
  //Serial.print(x);
  //Serial.print(", ");
  //Serial.print(th);
  //Serial.print(", ");
  Serial.println(ce);
  digitalWrite(ledPin, LOW);   // turn the ledPin off
  delay(200);                  // stop the program for some time
}
아두이노의 map명령은 여러모로 참 편한것 같습니다. 특히나 비례식 계산에는 복잡한 머리를 한결 가볍게 해주네요 ^^
실제 온도가 얼마인지 몰라서 오차가 얼마나 되는지 파악은 안되지만...
체리보드에서 측정된 온도와 1도 미만으로 차이 나더군요. 대충 비슷하게 맞는것 같습니다. ^^


Posted by pepsiman
comments powered by Disqus
CDS는 photo register 또는 photo cell 이라고도 부르며 빛의 밝기를 저항값으로 출력해주는 센서입니다.
PWM이란 펄스의 폭을 조절함으로써 전압을 제어하는 효과를 주는 기능으로 LED의 밝기를 조절한다거나 모터의 회전수를 조절하는등에 사용됩니다.

사용부품 : 220옴 2개, 10k옴 1개, led 2개
CDS가 스위치 역할을하여 초기상태보다 어두워지면 작동을 시작합니다.
즉 CDS의 빛을 가리면 작동을 시작합니다.

10번핀 LED는 천천히 켜졌다 어두워지고, 9번 LED는 빨리 켜졌다 어두워집니다.
두 속도가 다른 LED가 동시에 제어되는 예제입니다.

입력으로 CDS를 아날로그 0번 핀에 사용하고, 출력으로 LED 2개를 PWM 핀 9,10번에 연결했습니다.



      
위 동영상이 동작 모습입니다.

#include <stdio.h>

int photocellPin;
int buttonPin = 2;
int ledValue = LOW;

int cdsInitValue=0;
int fadeVal[12]={0};
long fadeTimer;

void InitCDS(int pin){
  photocellPin = pin;
  cdsInitValue=0;
  int i;
  for (i=0; i<10; i++){
    cdsInitValue +=  analogRead(photocellPin);
  }
  cdsInitValue = cdsInitValue / i;
}

int IsCDSOn(int val){
  int photocellReading = 0, i;
  for(i=0; i<3; i++){
    photocellReading += analogRead(photocellPin);
  }
  photocellReading /= i;
  
  char s[255];
  sprintf(s, "read=%d, initVal=%d\n", photocellReading, cdsInitValue);
  //Serial.print(s);
  
  if (val > 0){
    if (photocellReading > cdsInitValue + val)
      return 1;
    else
      return 0;
  }
  else {
    if (photocellReading < cdsInitValue + val)
      return 1;
    else
      return 0;
  }    
}

void InitFade(int val){
  for(int i=0; i<12; i++){
    fadeVal[i] = val;
  }
  fadeTimer=0;
}

int FadeCore(int pwmPin, int fadeSpeed, long startTime){
  char s[255];
  sprintf(s, "[%2d],timer=%ld, startTime=%ld\n",pwmPin, fadeTimer,startTime);
  Serial.print(s);
  if (fadeTimer < startTime) return fadeVal[pwmPin];
  
  fadeVal[pwmPin] += fadeSpeed;
  //char s[255];
  sprintf(s, "spd=%d, cnt=%d\n", fadeSpeed, fadeVal[pwmPin]);
  Serial.print(s);
  
  if (fadeVal[pwmPin] < 0) fadeVal[pwmPin] = 0;
  if (fadeVal[pwmPin] > 255) fadeVal[pwmPin] = 255;
  
  analogWrite(pwmPin, fadeVal[pwmPin]);
  /*
  if (fadeSpeed > 0){
    if (countFade < 255) return 1;
    else return 0;
  } else {
    if (countFade > 0) return 1;
    else return 0;
  }
  */
  return fadeVal[pwmPin];
}

void FadeDelay(long ms){
    delay(ms);
    fadeTimer += ms;
}

void Init(){
  int cdsPin = 0, startVal = 0;
  
  InitCDS(cdsPin);
  InitFade(startVal);
}

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

void loop(void) {
  int fadeStep=3, fadePin10=10,fadePin9=9, cdsSense=-40, val1=0, val2=255, timeDelay=10;
  
  while (IsCDSOn(cdsSense) == 0);
  
  InitFade(0);
  while(val1 < 255){
    val1 = FadeCore(fadePin10, fadeStep, 0);
    FadeCore(fadePin9, fadeStep*4, 80);
    Serial.println(val1);
    FadeDelay(timeDelay);
  }

  InitFade(255);
  while(val2 > 0){
    val2 = FadeCore(fadePin10, fadeStep * (-1), 0);
    FadeCore(fadePin9, fadeStep * (-4), 80);
    FadeDelay(timeDelay);
  }
}


Posted by pepsiman
comments powered by Disqus
위에 왼쪽에 보이는 것이 브레드 보드 입니다.
좌우 새로로 두줄로 되어 있는 부분을 버스 영역 이라고 하여 전원이 지나가는 선이고,
중앙에 가로로 5칸씩되어 있는 부분을 IC 영역이라고 하여 부품을 배치하는 곳입니다.
작은 구멍이 뚫려 있어 각종 부품들의 다리를 꽂는 것 만으로 회로를 구성 할수 있습니다.
납땜할 필요가 없기때문에 회로를 테스트하고 수정하기 쉽게 되어 있고 초보자들도 사용하기 쉽습니다.

내부구조는 오른쪽 사진 처럼 각 구멍이 연결되어 있습니다 IC 영역은 세로로 전체가 연결되어 있고
버스 영역은 가로로 5칸씩 연결되어 있습니다.






이 회로는 led를 켜기 위한 예시를 보여 줍니다.
전원은 버스 영역에 + - 를 연결하고 +에 저항을 연결하여 반대쪽을 버스 영역에 연결하고 LED는 두 IC 영역에 걸쳐 연결합니다.
다시 LED의 한쪽을 - 버스 영역에 연결하여 회로가 연결됩니다.




















실제로 부품들이 브레드보드에 꽂혀 있는 모습입니다.
왼쪽부터 CDS, LED, 저항, 스위치 입니다.
아래쪽에 점프 와이어가 꽂혀 있습니다.
Posted by pepsiman
comments powered by Disqus

티스토리 툴바