델파이로 병렬포트 이용하기...

어제 병렬포트에서 RF 센서의 입력을 받아야 하는 상황이 있었습니다.
그런데...포트를 읽을 때마다 255 (=0xFF, 0b11111111) 이더군요.
입력이 없는 Floating 상태에서는 내부적으로 풀업되어 있으니 255 가 나오는 것은 맞는데
2번핀을 25번핀에 연결했을 때는 254가 나와야 하는데 255 라서 곤란했습니다.

(병렬포트의 2번~9번 핀은 데이터 D0~D7 입니다., 18~25번 핀은 Ground 입니다.
2번핀을 25번핀에 연결하면
D7 D6 D5 D4 | D3 D2 D1 D0
  1   1   1   1     1   1   1   0    = 0b11111110 = 0xFE = 254
가 되어야 합니다.)

어제는 급해서...STROBE 핀을 이용해서 입력을 받았습니다. 날새고 한참 자고 일어나서 지금 책을 찾아보고 이유를 알았습니다.

병렬포트는 Control 포트를 이용하여 병렬 포트를 제어합니다. Data 포트의 입출력 방향도 바꿉니다.
C5 = 0 이면 Output 이고 C5 = 1 이면 Input 입니다.
따라서 Data 포트로 입력을 받으려면 C5에 1을 출력하고 Data 포트를 읽어야 했던 것입니다.

다음은 델파이 7에서 io.dll 을 이용해서 병렬포트를 통해 값을 출력하거나 입력받는 프로그램입니다.
io.dll 말고 다른 라이브러리를 사용할 경우 dll 참조부분과 함수 이름만 수정하시면 됩니다.


unit uMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

const DATA1 = $378;
const DATA2 = $278;
const STATUS1 = $379;
const STATUS2 = $279;
const CONTROL1 = $37A;
const CONTROL2 = $27A;

type
  TForm1 = class(TForm)
    btRead: TButton;
    Memo1: TMemo;
    edWriteValue: TEdit;
    btWrite: TButton;
    cbxSelPort: TComboBox;
    procedure btReadClick(Sender: TObject);
    procedure btWriteClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

procedure PortOut(Port : Word; Data : Byte); stdcall; external 'io.dll';
function PortIn(Port:Word):Byte; stdcall; external 'io.dll';

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.btReadClick(Sender: TObject);
var
  iTmpDataPort: Integer;
  iTmpControlPort: Integer;
  byInValue: Byte;
begin
  if cbxSelPort.Text = '0x378' then begin
    iTmpDataPort := DATA1;
    iTmpControlPort := CONTROL1;
  end;
  if cbxSelPort.Text = '0x278' then begin
    iTmpDataPort := DATA2;
    iTmpControlPort := CONTROL2;
  end;

  PortOut(iTmpControlPort, $2D);
  byInValue := PortIn(iTmpDataPort);
  PortOut(iTmpControlPort, $00);
  Memo1.Lines.Add(IntToStr(byInValue));

end;

procedure TForm1.btWriteClick(Sender: TObject);
var
  iTmpDataPort: Integer;
  iTmpControlPort: Integer;
  iOutValue: Integer;
begin
  if cbxSelPort.Text = '0x378' then begin
    iTmpDataPort := DATA1;
    iTmpControlPort := CONTROL1;
  end;
  if cbxSelPort.Text = '0x278' then begin
    iTmpDataPort := DATA2;
    iTmpControlPort := CONTROL2;
  end;

  if TryStrToInt(edWriteValue.Text, iOutValue) then begin
    if (0 <= iOutValue) AND (iOutValue <= 255) then
      PortOut(iTmpDataPort, iOutValue)
    else begin
      ShowMessage('병렬포트로 출력하실 값의 범위는 0부터 255까지 입니다.');
      edWriteValue.SetFocus;
      exit;
    end;

  end
  else begin
    ShowMessage('병렬포트로 출력하실 값은 0부터 255까지 입니다.');
    edWriteValue.SetFocus;
    exit;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Memo1.Clear;
end;

end.


위 소스는 잠에서 깨어 책보고 바로 만든 것입니다. 그래서 맘에 안드는 구석이 많은...깔끔해 보이지 않는 그런 소스입니다...만,
기능적으로 큰 문제는 없습니다.
...회사에서 사용할 때는 좀 더 이쁘게 다듬겠지요...;
배열도 쓰고 하드웨어 자원도 검색하고...등등...;;
아니면 병렬포트를 이용하는 컴포넌트라도 찾아서 사용하겠지요...;;;

여튼, 제가 네이버와 델코에서 엉뚱한 답때문에 삽질한 것이 억울해서 올립니다. 알고보면 아무것도 아닌데 찾아보면 찾기 힘들거나 찾아도 틀린 정보가 많은...그런 것이었습니다.
다른 분들은 저처럼 삽질하지 않으시기를...

by Dark-Ryu | 2009/06/04 00:08 | 델파이 | 트랙백 | 덧글(3)

[2008.04.05] 담에 걸려 눕지도 못하고 있습니다. ㅜ.ㅜ

금요일부터 고생하고 있습니다.
똑바로 누워도 옆으로 누워도 엎드려 누워도 아퍼서 잠을 제대로 못 자고 있습니다. ㅜ.ㅜ
토요일에 가서 침을 맞기는 했는데...한의사 말로는 호흡근 쪽에 침을 한번 더 맞아야 한다는 군요.
월요일에 맞고 출근하면 딱인데...으...

담의 원인은 뭐...항상 그러하듯이 꾸부정한 자세죠.
그런데 컴퓨터...그것도 조그만 노트북으로 주로 작업을 하다보니 좀...;
한의사분이 그러더군요. 접힌 어깨라고...
이번에 담 풀리고 나면 정말정말 주의할 겁니다. 이렇게 고통스럽다니...
한참 이런저런 잘 되는 상황에서 귀한 주말 시간이 날라갔습니다.
으휴...주말이 아니면 프로그램 작업을 할 시간이 없다는 것이 너무너무너무너무 싫습니다.
'더 큰 문제는 그런 상황에서 회사에서 뭐뭐 언제까지 되나요?'
'그럼 지금 할 수 있는 것이 뭔가요?'
따위의 질문을 하는 것이 더 짜증이 납니다.
...그런데 저는 그런 현실 속에서 일해야 하는 것이죠. 월급도 덜 들어오는 상황이라 뭐랄까 의욕이 반토막인데...
뭐...이런저런 짜증때문에 요새 일하기 정말 싫습니다.
회사를 옮기고 싶은 생각이 많이 들지만 ... 참고 있는 중입니다.
한 몇주만 더 고생해보고 심각하게 고민해봐야겠죠.

월급을 180 정도로 떨구고...이제는 100 만원씩만 준 것이 2달 째...노동부에 가기에는 조금 약하겠죠...

by Dark-Ryu | 2009/04/05 19:03 | 근황? | 트랙백 | 덧글(0)

선점형/비선점형 멀티태스킹...그리고 Synchronize

윈도우즈95 이후 현재의 비스타까지의 윈도우즈는 선점형 멀티태스킹을 지원한다.
선점형은 비선점형에 비해 여러가지 장점이 있다고 알려져 있다.
그런데 일반 사람들은 이 둘의 차이를 잘 모르고 '아~ 좋은 거구나' 하고 넘어가는 경우가 많다.
그리고...심지어는 프로그래머조차도 이 둘의 차이를 잘 모르는 경우가 있다.

손전등 한개만 가지고 어두운 곳에서의 야간 공사를 할 경우, 한사람이 손전등을 가지고 작업을 하는 동안 다른 사람들은 작업을 할 수 없을 것이다.
누군가가 작업을 하고 있는데 다른 사람이 손전등 좀 달라고 할 때 '좀 기다려봐 나 아직 안 끝났어' 하고 손전등을 넘기지 않으면 손전등을 가지고 있지 않은 사람은 답답해도 그냥 기다릴 수 밖에 없는 경우가 선점형이다.
누구든 손전등을 먼저 잡은 사람이 장땡인 것이다.
그런데 만약 손전등을 달라고 하는 사람이 사장님이면 어쩔 것인가? 손전등을 줄 수 밖에 없을 것이다. 이것이 비선점형이다. 먼저 손전등을 집었어도 사장님이 달라고 하면 넘겨줘야 하는 것이다.

단일 쓰레드 환경에 익숙한 사람들은 비선점형 멀티태스킹까지는 쉽게 이해한다.
비선점형 멀티태스킹에서 태스크를 어떤 특정 이벤트가 발생했을 때 처리되는 독립적인 함수라는 식으로 생각을 확장하기도 한다. 일단 함수가 호출되면 다른 함수들은 그 함수가 처리되기 전까지는 기다려야 하고 호출된 함수는 다른 함수들을 고려할 필요가 없는 것이다. 비선점형에서의 태스크와 비슷하지 않는가?
그렇지만 선점형 멀티태스킹은 이런 식으로 생각 할 수가 없다.
태스크를 수행하고 있다가도 자신보다 우선순위가 큰 태스크가 제어권을 요청하면 제어권을 넘겨야하는 것이다.
제어권 요청 순서는 동일 우선순위 태스크일 경우에만 중요할 뿐 우선순위가 다르다면 아무런 의미가 없다.

그림을 그리는 태스크와 그림을 액자에 넣어 벽에 거는 태스크가 있다.
직감적으로 알 수 있듯이 그림을 그리는 태스크가 그림을 액자에 넣어 벽에 거는 태스크보다 시간이 더 오래 걸린다.
그런데 만약 그림을 액자에 넣어 벽에 거는 태스크가 우선 순위가 높다면 어떤 일이 벌어질까?
완성되지 않을 그림이 액자에 넣어져 벽에 걸리 수 있을 것이다.

멀티 태스킹에서 이런 문제를 공유자원에 대한 동기화 문제라고 한다.
...어려운 말이다.

일반적으로 델파이의 TComponent는 쓰레드에 대해 안전하지 않다. 델파이의 VCL 중 이 클래스의 후손들도 쓰레드에 대해 안전하지 않다. 쓰레드 내부에서 VCL의 시각적인 요소들을 사용하려고 시도한다면 문제가 발생할 것이다.
이런 문제를 막기 위해서는 쓰레드 동기화를 위해 Critical section 혹은 뮤텍스 등을 이용해 VCL 코드의 일정 부분을 wrapping 해야만 하는데 이런 부분이 있으면 VCL은 눈에 띄게 더 커지고 느려진다.
이런 상황을 피하는 방법으로 TThread 객체의 Synchronize 함수가 제공된다.
이 함수는 쓰레드 내부에서 VCL을 호출할 수 있게 해주는 것으로 쓰레드 local storage에 대해 10배 정도 더 빠른 대안을 제공한다.

'Synchronize는 쓰레드가 일시적으로 애플리케이션의 메인 쓰레드의 일부가 되도록 해준다. synchronize가 호출될 때 메인 쓰레드가 실행되지 않는다. VCL은 다른 어떤 메시지들도 받을 수 없고 그래서 Synchronize가 실행되는 시간 동안 VCL의 속성과 메쏘드에 안전하게 접근하거나 호출할 수 있다.'
...머리가 나쁜 나로써는 이 문장을 그냥 이렇게 이해하는 수밖에 없다.
Synchronize를 호출하면 일시적으로 비선점형처럼 동작한다.

이것이 맞는지는 실험을 해봐야 할 것이다.
.........아직 확신하는 것은 아니라는 소리다.
그런데 여기 글을 쓰는 것은 머리가 나쁜 나로써는 일과 생활에 치여 까먹기 일쑤이기 때문에 기록을 남기는 것이다.
시간나면 확인할 수 있는 프로그램을 짜봐야할 듯...

2009.05.05. 선점형과 비선점형을 반대로 써놓는 큰 실수를 저질렀다...왜 이런 부분은 한글보다 영어가 더 안 헷갈리는지 모르겠다.

by Dark-Ryu | 2009/04/03 09:59 | 델파이 | 트랙백 | 덧글(2)

Sleep(0)의 의미

Sleep() 함수는 밀리초(millisecond, 1/1000) 단위의 시간을 매개변수로 입력 받아 해당 프로그램을 '대기(Suspend)'시키는 역할을 한다.

윈도우에서 대부분의 프로그램(프로세스 또는 작업)은 동일한 우선순위(Priority)로 동작한다. 따라서 CPU 사용 시간과 자원을 각 프로그램에게 동일하게 할당한다. Sleep() 함수를 사용하면, 해당 프로그램은 대기 상태로 전환되고 다른 프로그램에게 자원을 양보하게 되는 것이다.

Sleep(0) 은 언뜻 보면 의미없어보일 수도 있다. 실제 어떤 개발자는 Sleep(0) 을 주면 해당 프로그램은 무한 루프와 비슷한 상태로 동작한다고 하는 경우도 봤다.
그러나 실제로 Sleep(0)을 사용하면 '스위칭(Switching)'이 발생한다. 즉, 이 구문을 사용하는 순간 같은 우선 순위에 있는 다른 프로그램이 동작한다. 하지만 대기 시간이 0초이므로 우선 순위기 낮은 프로그램에게는 실행 기회가 주어지지 않는다.
따라서 우선 순위가 높은 프로그램에서 Sleep(0) 을 사용했을 경우 스위칭이 발생하지 않고 모든 자원을 독점하는 듯이 보일 수도 있는 것이다.

Sleep() 함수의 이런 특징들은 응용 프로그램에서 직접 관리하는 멀티 스레딩에도 적용된다. 따라서 멀티 스레드 프로그래밍에서, 여러 스레드가 모두 효율적으로 동작할 수 있도록 하기 위해서는 우선 순위 지정과 함께 Sleep() 함수를 잘 사용해야 한다.

by Dark-Ryu | 2009/03/20 20:29 | 델파이 | 트랙백 | 덧글(0)

[2009.03.18] 요즘 잘 나가고 (?) 있습니다.

...회사 밖으로 말이죠. ^^;
농협의 환율 표시기에 한해서지만 요새 회사 물건이 잘 나가고 있습니다.
그.런.데. 제가 열심히 설치 뛰고 있습니다. ;;
사무실에서 프로그램할 시간이 없습니다. 공부할 시간도 없습니다. 업무조율할 시간도 없습니다.
사무실에서 SetTop(이라고 쓰지만 그냥 PC 죠 ^^;) 조립하고 윈도우 설치하고 드라이버 잡고 프로그램 설치하고 설정하고 하다보면 나가야할 시간이고...
그래서 오늘 몰아서 미리 조립해 놓으려 했더니 자재가 부족하여 좌절입니다. 분명 어제 전화했기 때문에 오늘 도착해야했는데 말이죠.
내일은 수원 쪽의 마도 농협으로 설치하러 가야하는데...큰 일입니다.
내일 아침까지 자재가 안 오면 난감한데 말이죠...;
여튼 온다고 해도...멀군요. 후우...
일 끝나고 집에 어떻게 갈지...
게다가 개발 업무를 못해서 일정이 또 꼬였습니다.
영업 쪽에서 사정을 알고 있으니 뭐라고 채근하지는 않겠지만 일정이 밀린 것은 밀린 것...그래서 토요일에 출근하게 될지도 모릅니다.
아...집사람 요즘 기분이 완전 바닥을 치고 있는데 토요일에 같이 산후 조리원 알아보기로 했는데...미치겠습니다. 회사가 우리 부부를 갈라놓을지도 모른다는 생각을 하면서 열심히 바닥을 긁고 있습니다. ㅜ.ㅜ

현재 델파이로 작업을 하는데 델파이로 하다보니 비주얼 C++ 이 궁금해져버렸습니다.
그래서 책을 좀 샀는데...아뿔싸...초보용 책만 3권이 되어 버렸습니다. ;;;
난감한 상황이죠...우선 쌓아놓고서 손에 잡히는대로 보기는 하지만...결국에는 가장 얇은 책을 가장 자주 보게 됩니다. ^^;;
좀 차분하게 앉아서 비주얼 C++ 로 현재 작업하고 있는 것과 비슷한 흉내를 내봐야하는데 시간이 없네요.
흉내가 잘 되면 환경을 비주얼 C++ 로 옮겨볼까 하는 생각도 하고 있습니다.

.NET 이라는 것에 호기심도 생겨서 '김상형' 이라는 유명하신 분이 쓰신 책도 한 권 샀습니다.
C# 가 주가 되는 것이죠...써먹을 일이 있을지는 모르겠지만 멋진 환경이라고 하더군요.;;;
'조엘 온 소프트웨어' 라는 책이 있습니다. 요새 시간 날 때마다 손에 잡히는대로 보고 있습니다.
책 잡고 페이지 열어서 아무 곳이나 나오는 곳에서부터 읽고 있습니다.
좋은 책입니다. 덕분에 요즘에는 업무환경이라는 것에 대해서 고민하고 있습니다.
역시...책도 사고(;;) 준비중입니다. 실제 업무에 사용할 수 있을지는 미지수입니다. 아무래도 개발환경이 델파이다 보니...;
서브버전 정도는 사용할 수 있을 것 같은데 그 이외의 툴들은 못 쓸지도 모르겠습니다.

'피플웨어' 라는 책은 사려다가 번역이 난감하다는 서평을 보고서 안 샀습니다.
그러나 오늘 마구마구 사고 싶어졌습니다.
사서 회사에 둬서 다른 사람들이 좀 읽게 하고 싶었습니다.
뭐...관뒀습니다. 에효...

집사람과 다시 원만해졌으면 좋겠습니다. 불안불안하면서도 많이 행복했는데...집사람이 화를 풀어주기만 한다면 뭐든지 해주고 싶습니다.

돈이 필요한데 투잡은 커녕 현재 업무 처리할 시간도 부족합니다.
....실은 잠잘 시간도 부족합니다.
요즘 몸이 좀 이상하죠. 저는 요새 종종...지진을 느낍니다.
....저 혼자만 느끼는 지진이죠. (먼산)
땅이 울렁거린답니다. 그런데 다른 사람들은 못 느끼고 저만 그럽니다. ㅜ.ㅜ
그리고 머리가 아픕니다. 두통하고는 좀 다른데...음...어디 쾅 부딪치고 나서 멍든 것처럼 아픕니다.
오른쪽 귀 근처였는데 오늘은 정수리 왼쪽 부근입니다.
묘하게 졸리고 머리 아프고...
오늘 집에 와서는 담까지 걸려버렸습니다.

몸무게는....86에서 현재 78 로...한달 반 사이 쭉 빠졌습니다. 이전 몸무게는 확실히 과체중이고 지금 몸무게도 과체중이기는 하지만...한달 반 사이에 8 킬로...운동도 안 했는데...난감하죠...;;
지방보다 근육량이 줄어든 기분입니다. ㅠ.ㅠ

감기도 2달째를 넘어가고 있습니다. 후우...
초기에 약먹고 나아갔는데 야근, 날샘, 휴일 근무, 등등을 이어가다보니 안 떨어지네요.
약 떨어졌는데 병원에도 못 가고 있습니다.
의사 선생님은 제 감기가 완전히 나았다고 생각할 지도 모르겠군요.

여튼 종합적으로 힘드네요. 그래도 이래저래 나아가고 있습니다. 최대한 짬나는 대로 노력하면서 나아가고 있습니다.
힘들지만 최선을 다해서 살아가고 있습니다. 그래서 고통스럽지만 불행하지는 않습니다.
....물론 여기서 조금 더 힘들어지면 불행하다고 생각할 지도 모르겠네요. ^^; (먼산)

여튼 힘내서 열심히 살겠습니다.

by Dark-Ryu | 2009/03/18 23:44 | 근황? | 트랙백 | 덧글(0)

<< 이전 페이지다음 페이지 >>