LED PWM을 통한 밝기 제어.

.

http://cafe.naver.com/openrt/6336 참고


우선 라즈베리파이의 핀 배치는 아래와 같다. 우리는 이번 실험에서6번과 12번 핀을 사용!!




위 참고 사이트를 기반으로 입력을 받으면 밝기가 변하는 프로그램을 만들기가 오늘의 목표.


1. 코드는 아래와 같다.


2. 그리고 gcc -o pwm LED_pwm_test1.c -lwiringPi -lpthread 를 입력한 뒤 

새로 생성된 파일을 보면 아래와 같다.

pwm 이라는 초록색 글씨의 실행파일이 컴파일된 후 만들어진 것을 확인할 수 있다.


3. 이제 실행을 해보자! sudo ./pwm 입력!


0~11 까지 입력하면 LED가 점점 밝아진다.

그리고 Ctrl+C를 눌러 종료하면 된다.


작동영상과 사진!







설정

트랙백

댓글

8-2. PWM 서보모터 DC등을 제어 위해 여러개 핀에 PWM 줘서 제대로 나오는지 확인하기.


설정

트랙백

댓글

10. 시리얼 통신 헤더파일(wiringSerial.h) 분석. 인터럽트처럼 동작할 수 있게 코드변환.

9에서 배운 것처럼 통신을 하면 되지만. 우리가 원하는 통신은,

자동차 방향이 가운데를 유지하다가 신호가 오면 좌우로 변환되고, 신호가 없으면 다시 가운데를 유지하도록 하는 것이다.


이렇게 하려면 if 등의 조건문이 필요한데... 일단 목표는 LED를 3개 놓고 평소에는 가운데를 입력 받다가 L 누르면 왼쪽 그리고 가만히 있으면 다시 가운데 불켜지고, R 누르면 오른쪽 켜지는 것을 구현하는 것이다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <stdio.h>
#include <string.h>
#include <errno.h>
 
#include <wiringPi.h>
#include <softPwm.h>
#include <wiringSerial.h>
 
int main ()
{
  int fd ; //시리얼 통신 확인 변수
  int count ;
  unsigned int nextTime ;
 
  if ((fd = serialOpen ("/dev/ttyAMA0", 115200)) < 0)  // 두번째 인자값이 보레이트 설정
  {   // fd가 -1이면 아래 처럼 unable 나온다.
    fprintf (stderr, "Unable to open serial device: %s\n", strerror (errno)) ;                   
    return 1 ;
  }
 
  if (wiringPiSetup () == -1)
  {
    fprintf (stdout, "Unable to start wiringPi: %s\n", strerror (errno)) ;
    return 1 ;
  }
 ////////////////////////////////////////////별거 아님////////////////////////////////////////////////
 
  nextTime = millis () + 300 ;
 
  while(1) 
  {
      scanf("%d", &count);  // 통신확인 안되서 임의로 테스트 해볼 수 있게 scanf
      fflush (stdout) ;
      serialPutchar (fd, count) ; // 데이터 전송해주는 함수
      nextTime += 300 ; //delay 역할?
    
       if(getchar == 1)  // 제일 왼쪽
       {
           softPwmWrite(ledMap[0], values[7]);
       }
    
       else if(getchar ==6)  // 제일 오른쪽
       {
           softPwmWrite(ledMap[7], values[7]);
       }
    
       else
       {
           softPwmWrite(ledMap[3], values[7]);   //빵판의 LED 3,4가 centre
           softPwmWrite(ledMap[4], values[7]);
       }
  
 //////////////////////////////////////////////////////////////////
    delay (3) ;
 
    while (serialDataAvail (fd)) // RX에 데이터 들어오는지 확인하는 함수
    {
      printf (" -> %3d", serialGetchar (fd)) ;  // RX 데이터 받는 함수
      fflush (stdout) ;
    }
  }
 
  printf ("\n") ;
  return 0 ;
}


설정

트랙백

댓글

9. 시리얼통신-라즈베리 통신하기-후에 블루투스로 통신

참고1 .http://embejide.tistory.com/40 (http://cafe.naver.com/pipc/2169)

          http://blog.naver.com/kimyosep0331/140194362360

참고2. http://cafe.naver.com/openrt/484


1. 일단 /boot/cmdline.txt 파일 백업하고 sudo cp cmdline.txt cmdline_backup.txt 를 입력    해서 원본을 복사한다.

~로 시작하는건 일종의 C드라이브 개념이고. "cd /"를 해야 더 상위인 root에 갈 수 있다.


2. 참고1 블로그에 있는 것처럼 cmdline.txt 내용을 지우면...

이상하게 에러가 난다.

원인은 read only이기 때문!  설정을 바꿔주기 위해 모드를 변경한다.

ls -al로 전체 파일 조건을 보고

sudo chmod 777 로 모든 권한을 조정한다.

그리고 텍스트파일 켜서 

삭제.                                                                                                  (출처 참고1).


3. 이제 cd .. -> etc경로 -> inittab파일을 수정한다.


맨 아래줄에 T0:23raspawn:/sbin/getty -L ttyAMA0 115200 vt100 이라고 적혀있는놈을 주석처리해준다.

저장하고 sudo reboot 명령어를 사용해서 라즈베리파이를 재부팅해준다.

#이 주석...                                                                                      (출처 참고1).


4. 자 이제 wiringPi/examples 폴더로 이동해서 make serialTest를 입력하고 serialTest를 컴파일한다. 컴파일을 완료하고 GPIO핀을 아래 그림처럼 연결하면 하드웨어도 준비 끝이다. 일단 루프백테스트를 하기위함이다. 루프백테스트는 rx핀과 tx핀을 연결하고 데이터를 보내고 읽는 테스트다. 즉 자기자신한테 데이터를 보내고 받는것이다.


 (출처 참고1).

sudo ./serialTest 를 입력해서 확인해본다.

serialTest.c 코드


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <stdio.h>
#include <string.h>
#include <errno.h>
 
#include <wiringPi.h>
#include <wiringSerial.h>
 
int main ()
{
  int fd ; //시리얼 통신 확인 변수
  int count ;
  unsigned int nextTime ;
 
  if ((fd = serialOpen ("/dev/ttyAMA0", 115200)) < 0)  // 두번째 인자값이 보레이트 설정
  {   // fd가 -1이면 아래 처럼 unable 나온다.
    fprintf (stderr, "Unable to open serial device: %s\n", strerror (errno)) ;                   
    return 1 ;
  }
 
  if (wiringPiSetup () == -1)
  {
    fprintf (stdout, "Unable to start wiringPi: %s\n", strerror (errno)) ;
    return 1 ;
  }
 
  nextTime = millis () + 300 ;   // millis() 함수는 값이 일정하게 증가하는 함수
 
  for (count = 0 ; count < 256 ; )   //
  {
    if (millis () > nextTime)
    {
      printf ("\nOut: %d: ", count) ;
      fflush (stdout) ;                //뭐하는 변수인지... fflush
      serialPutchar (fd, count) ; // 데이터 전송해주는 함수, count 값이 TX로 가나보다.
      nextTime += 300 ; //delay 역할?
      ++count ;
    }
 
    delay (3) ;
 
    while (serialDataAvail (fd))  // DataAvail은 Rx에 신호가 있을 때 실행됨.
    {
      printf (" -> %3d", serialGetchar (fd)) ;  // 데이터 받는 함수
      fflush (stdout) ;
    }
  }
 
  printf ("\n") ;
  return 0 ;
}

코드를 분석해보자!

26번줄의 millis() 함수는 어느 값에서 부터 일정하게 조금씩 증가하는 함수로 판명되었다. 

30~37번의 if문을 보면 millis()가 netxTime보다 커야 하는데 이것은 처음부터 불가능하므로 millis()함수가 일정하게 증가하는 것으로 볼 수 있고 이것이 +next값을 넘을 때마다 if문이 실행되는 것을 알 수있다. 또 +next가 되고 그것이 또 커지면 if문 실행.


 41~46번줄의 serialDataAvail 함수는 RX에 입력이 있을 때 1을 출력하는 함수로 판명되었다. 그래서 while문이 실행된거지. 확인을 위해 int a=0;을 선언하고 아래와 같이 코드를 작성.

결과는 아래처럼 나온다.





5. 이제 실행해보면! TX -> RX 출력이 보인다.

설정

트랙백

댓글

8. PWM 이용한 서보모터 제어.


먼저 서보모터의 개요이다. 사진처럼, -90에서 +90까지 움직이는데 필요한 duty 시간이 나와있다.


주기가 2ms, 20ms, 40ms 상관없이 high 시그널이 0.6ms동안 오면 -90인 것이다.

따라서 이렇게 하기 위해서 코드를 수정해보면.


RANGE가 1000이었을 때 실제 100ms 였으니까. 6이면 0.6ms 이겠구나.


많이 고칠 것도 없다.

 39             while(1)  //infinite loop
 40             {
 41             softPwmWrite (ledMap [1], 6);  // value=는 없고 그냥 0.6ms 일 뿐이다
 42             delay (50) ;
 43             }

여태껏 values[]를 배열형태로 값을 정해놨었는데 그냥 6하면 0.6ms duty값을 줄 수 있다.



0.6 밀리세크!!!


원래는 빵판에 서보모터까지 세팅해놓고 실험하려 했으나 라즈베리파이에 보호회로가 없어서 위험할 수 도 있다는 염려에 나중에 하기로 했다 +_+;;; 

왜 위험한건지는 아직 그냥 느낌... 참고자료->(http://cafe.naver.com/openrt/224)


완성된 코드


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
 #include <stdio.h>
 #include <errno.h>
 #include <string.h>
 
 #include <wiringPi.h>
 #include <softPwm.h>
 
 #define RANGE      500    //이렇게 하면 주기가 50ms이다.
 #define NUM_LEDS   12
 
 int ledMap [NUM_LEDS] = { 0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13 } ;
 
 int values [NUM_LEDS] = { 0, 17, 32, 50, 67, 85, 100, 85, 67, 50, 32, 17 } ; //이건 듀티비!!!
 
 int main ()
 {
     int i ;
     char buf [80] ;   // buffer
 
     if (wiringPiSetup () == -1)
         {
           fprintf (stdout, "oops: %s\n", strerror (errno)) ;
           return 1 ;
         }
 
     for (i = 0 ; i < NUM_LEDS ; ++i)
         {
           softPwmCreate (ledMap [i], 0, RANGE) ;
           printf ("%3d, %3d, %3d\n", i, ledMap [i], values [i]) ;
         }
 
 ///////////////////////////////////////////////////////////////step1//
 
       fgets (buf, 80, stdin) ; ////////////////////act as scanf(put in anyth
 
             // Bring all up one by one
 
            while(1)  //infinite loop
             {
             softPwmWrite (ledMap [1], 6);  // value=는 없고 그냥 0.6ms 일 뿐이다
             delay (50) ;
             }
}


설정

트랙백

댓글

7.wiringPi를 이용한 PWM 실험.


지금 주기와 듀티비를 알아내는 것이 관건인데...

 1

  2 #include <stdio.h>
  3 #include <errno.h>
  4 #include <string.h>
  5
  6 #include <wiringPi.h>
  7 #include <softPwm.h>
  8
  9 #define RANGE      500    //이렇게 하면 주기가 50ms이다.
 10 #define NUM_LEDS   12
 11
 12 int ledMap [NUM_LEDS] = { 0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13 } ;
 13
 14 int values [NUM_LEDS] = { 0, 17, 32, 50, 67, 85, 100, 85, 67, 50, 32, 17 } ; //이건 듀티비!!!
 15
 16 int main ()
 17 {
 18     int i ;
 19     char buf [80] ;   // buffer
 20
 21     if (wiringPiSetup () == -1)
 22         {
 23           fprintf (stdout, "oops: %s\n", strerror (errno)) ;
 24           return 1 ;
 25         }
 26
 27     for (i = 0 ; i < NUM_LEDS ; ++i)
 28         {
 29           softPwmCreate (ledMap [i], 0, RANGE) ;
 30           printf ("%3d, %3d, %3d\n", i, ledMap [i], values [i]) ;
 31         }
 32
 33 ///////////////////////////////////////////////////////////////step1//
 34
 35       fgets (buf, 80, stdin) ; ////////////////////act as scanf(put in anyth
 36
 37             // Bring all up one by one
 38
 39             while(1)  //infinite loop
 40             {
 41             softPwmWrite (ledMap [1], values [6]);  // value=50
 42             delay (50) ;
 43             }
 44 }
 


위처럼 면, softPwmWrite (ledMap [1], values [6])를 했더니 (4편에 빵판사진 LED)

 두 번째 LED가 켜지고 주기는 매우 짧았다;;

1
2
3
4
5
 39             while(1)  //infinite loop
 40             {
 41             softPwmWrite (ledMap [1], values [6]);  // value=50
 42             delay (50) ;
 43             }


LED 는 위 배열에서 1값일거고...밸류가 듀티비인가..

     

보면 주기는 50ms

RANGE를 주파수라 생각하고 500 ㅡ> 주기는 20ms로 생각했는데 실제는 50ms

values는 여전히 듀티비(%)라 가정하고 다시 조정해보자.


values [3] (실제 50)으로 하니까 high인 폭이 더 짧아졌다. (duty비 맞는듯)

그리고 high가 너무 짧아서 LED도 더 어둡게 깜빡인다. 깜빡이는 속도는 같다.


다시 values [6] 해놓고 RANGE만 1000으로 바꿔보았다. LED가 더 느리게 깜빡인다.

 아하... 주기가 100ms가 되었다.


RANGE 1은 0.1ms이다.


자 그럼 위 오실로 사진을 보면 주기는 100ms이고 

RANGE 1000에 values [6](100)을 적용하면 전체주기의 10%만 high값이 출력된다.


만약 주기20ms를 맞추기 위해 RANGE 200, 그리고 values [6](100)을 적용하면

 10ms동안 high가 출력된다.



이제 PWM은 어느정도 완료된듯!


여기서 내가 주기 20ms를 꼭 맞추려고 하는 이유가 있다.

주기가 20ms 라는 것은 20ms 마다 한번씩 파형을 발생시키는 것인데

서보모터 입장에서 20ms 보다 주기가 짧으면 더 많이 모터가 움찔?거려야 하므로 뜨거워진다.

20ms 주기가 서보모터에겐 가장 이상적인 조건이라 한다.

설정

트랙백

댓글

6. 지갑잃어버림, 노트북 무선랜카드 망가진듯...

어제는 셔틀버스에 지갑을 두고 내려서 고생하고, 오늘은 노트북 무선인터넷이 잡히지 않는다. 뭘까... 아예 전원이 안가는듯 하다.

   네트워크 어댑터에 보면 무선랜도 안잡히고...

레노버 원격 서비스센터에 연락해서 BIOS초기화 (F2 - F9)를 했더니, 안된다. 허허... 여전히 무선랜이 잡히지 않네... 서비스센터가서 견적 뽑아야겠다. 노트북이 엄청나게 뜨겁다...



다음부터는 ssh 켜놓고 어디 가지 않고 꼭 절전이나 전원을 끄기 ㅜㅜ

어댑그래서 파장시장쪽에 있는 레노버센터가보니 다향히 9월2일까지는 무상지원기간이나 ..

        

요놈의 무선랜카드가 쇼트가 됫는지 전원을 연결하면 뜨거워진다. 그리고 노트북 청소를 6개월에 한번씩은 해야될 것 같다. 환풍구가 먼지로 가득하다;;;


=================================================================================



설정

트랙백

댓글

5. 랜 케이블 하나로 라즈베리파이 접속하기

http://www.rasplay.org/?p=2804

http://www.icbanq.com/pbloger/board_View.aspx?number=241&boardNum=

일단 말하자면, 다소 복잡하고 어렵다. IPv4 고정아이피, 자동으로 재설정 등등;;

이번 세팅을 위해선 사전에 반드시 모니터와 마우스 키보드가 라즈베리에 붙어야한다!


위에 나온 사이트 처럼 똑같이 따라했다. 그런데 네트워크 및 인터넷이 없고 난 좀 달랐다;; 같은 윈 7인데.


밑에는 연결하기 전의 모습. 오른쪽에 아무것도 뜨지 않는다.




1. 에 사진 보면 라즈베리랑 UTP선을 연결하니까 떳다. 




2. 리고 밑에 처럼 IPv4 주소를 잘 저장해 둔다.




3. 제 라즈베리를 모니터랑 키보드에 연결해서, root 경로에 있는cmdline.txt.를 만져준다. 그런데 문제가 있음. read only라서 권한을 변경해줘야 함!

sudo chmod 777 cmdline.txt

그리고 나서 끝에 add : ip=내아이피 를 써준다(참고로 입력하는게 진짜 이상하고 어려웠다).




4. 망할.. 문제가 생겼다. 라즈베리를 껏다 켜거나 설정이 바뀔 때마다 2번의 IPv4 주소가 계속 바뀐다. 이러면 txt에 아이피를 계속 바꿔줘야 되는데 그러면 못쓴다...

도움을 받아, 라즈베리에 ip를 고정시키고 노트북도 ip를 고정으로 쓰기로 했다.

먼저 라즈베리를 아래와 같이

-1.  vi/etc/network/interfaces 에 간다.(tab 치면 자동완성)

-2. 가서 ip주소를 원하는대로 바꾼다(1.1.1.1도 된다). 나는 일관성을 위해...

-3. service networking restart 입력 -> 초기화

-4. ifconfig로 확인 (윈도우에서나 ipconfig)

--위 사진처럼 ip와 마스크등이 나타난다. 넷 마스크도 2번 사진처럼 설정함.





5. 이제는 노트북도 이에 맞게 설정해준다. 169.254.90.42가 라즈베리였으니까 나는 그냥 169.254.90.43으로 바꿨다.

-1. 여기로 가서 IPv4 빨간줄 더블클릭

-2. 위처럼 세팅(이것도 그냥 쳐도 되지만 그냥그냥...)

이렇게 확인버튼을 누르고 나서 실행-cmd-에서 핑을 날려보자.

라즈베리로 핑을 날렸더니 응답이 온다!! 연결이 되었다는 뜻.




6. putty에서 이제 해당 아이피를 설정해주고 저장~(포트 번호는 22번이 기본이다 이것 또한 바꿀 수 있다)

direct라고 이름을 지었다.

연결 성공! 완벽하다.





7. 이제 조심해야 할 점!

IP를 수동으로 할당했으므로 이대로 랜선을 뽑고 인터넷을 하면 접속이 안된다(DHCP ip 주소 자동할당?)


따라서 반드시

자동으로 IP 주소 받기를 설정하고 꺼야한다!

=========================================================================================================

아니면 강희형이 만들어준

라즈베리연결.bat    -> 라즈베리 연결용

자동ip.bat              -> 인터넷 연결용

이 파일들을 이용하여 더블클릭으로 설정한다.

라즈베리 사용 후엔 반드시 자동ip로 설정을 해놓아야한다.


완료화면. ifconfig, ip route 확인.




최종결론은 이것이 공유기에 라즈베리파이를 꼽는 것과 동일하다는 것이다.

노트북이 인터넷만 가능하면 라즈베리파이도 인터넷을 이용하여 파일을 주고받을 수 있다.(Filezillar 가능) 하지만 사진 업로드가 안된다...

=========================================================================================================




마우스, 키보드, 흐드미, 랜케이블까지 덕지덕지.

설정

트랙백

댓글