이번 포스팅에서는 433MHz 무선통신 모듈 사용에 대해 전해드리겠습니다.


우선 보통 무선통신 모듈 하면 블루투스나 와이파이가 가장 흔히 사용이 되는데, 아무래도 통신거리에 제한이 많기때문에 원거리 조종이  필요한 경우에는 RF 모듈을 사용하죠.


이번에 사용할 모듈스펙을 볼까요? 

모듈명 : AS07-M1101S (중국 카피제품인듯 합니다ㅎㅎ 'CC1101 Module' 로 검색하시면 자료를 더 찾으실 수 있어요!)

RF주파수 : 420 ~ 450MHz

통신 거리 : ~ 1Km

인가 전압 : 1.8 ~ 3.6V

가동 온도 : -40 ~ 85 

데이터 전송 속도 : ~ 500Kb/s

소모 전류 : ~17mA(수신), ~30mA(송신)


이 모듈을 이용하면 최장 1km가 떨어진 거리에서도 데이터 송수신이 가능하다고 합니다...!!

(하지만 장애물이 있는 실내의 경우 테스트결과 100~200m 만 넘어가도 데이터 송수신이 원활하지가 않더라구요...ㅠㅠ)



이번엔 아두이노 보드 2개와 433MHz 통신모듈 2개로 각각 송신기기, 수신기기를 만들어보겠습니다.


우선 핀배치가 1.27pitch여서 기존 빵판(2.54 pitch)에 사용할수 없기때문에 손수 납땜을 통해 와이어링을 했습니다.


납땜에 자신이 없으신 분은 1.27pitch 에서 2.54pitch로 변환해주는 보드를 구매하시거나, 1.27pitch의 PCB 만능기판에 납땜하셔서 1칸씩 건너뛰어 와이어링 하시면 2.54pitch에 맞게 사용하실 수 있어요^^



자 이제 전선도 뽑아냈으니, 아두이노와 연결해볼까요~?


우선 본 무선통신 모듈은 아두이노와 연결되어 SPI통신을 통해 데이터를 주고받습니다.

SPI통신이란 Serial Peripheral Interface의 줄임말로, 모토로라에서 고안해낸 통신방식입니다.

이 통신은 하나의 Master 모듈과 여러개의 Slave 모듈이 연결되는 (Peripheral) 방식의 통신으로, 


MISO (Master Input Slave Output) : Master기준 입력신호

MOSI (Master Output Slave Input) : Master기준 출력신호

SCK (Serial Clock) : Master로부터 나오는 Clock (신호 동기화를 위한 Clock)

SS (Slave Select) : 여러개의 Slave모듈이 연결되었을때, 특정 모듈을 선택하여 통신할수 있게끔 해주는 신호 (Enable 핀과 비슷한 역할을 합니다)


위와 같은 총 네개의 핀으로 통신을 합니다.

더 구체적인 내용들은 통신에 대한 설명 포스팅에서 자세히 다루겠습니다^^


자 그럼 아두이노와 무선모듈을 어떻게 연결하면 될까요?


  <433MHz 모듈>    <아두이노>


GOD0    ------       2

GOD2    ------       9

CSN/SS  ------      10

MISO*    ------      11

MOSI     ------      12

SCK       ------      13

VCC       ------    3.3V

GND      ------    GND


(아무래도 GOD1핀에 대한 설명이 부족해서 찾질 못했지만, 테스트해보니 MISO핀이 맞습니다.)



송신모듈 (Transmitter)



#include <ELECHOUSE_CC1101.h>


#define size 11


byte TX_buffer[size]={0};

byte i;


void setup()

{

  Serial.begin(9600);

  ELECHOUSE_cc1101.Init();

  for(i=0;i<size;i++)

  {

     TX_buffer[i]=i;

  }

}


void loop()

{

  ELECHOUSE_cc1101.SendData(TX_buffer,size);

  delay(1);

}




수신모듈(Receiver)





#include <ELECHOUSE_CC1101.h>

 

 void setup()

{

  Serial.begin(9600);

  ELECHOUSE_cc1101.Init();

  ELECHOUSE_cc1101.SetReceive();

}


byte RX_buffer[11]={0};

byte size,i,flag;


void loop()

{

  if(ELECHOUSE_cc1101.CheckReceiveFlag())

  {

    size=ELECHOUSE_cc1101.ReceiveData(RX_buffer);

    for(i=0;i<size;i++)

    {

      Serial.print(RX_buffer[i],DEC);

      Serial.print("  ");

    }

    Serial.println("");

    ELECHOUSE_cc1101.SetReceive();

  }

}




각각의 모듈에 위 코드를 심어주고, Receiver모듈을 잡아서 시리얼 모니터를 보시게되면 아래와 같이 0~10까지 Transmitter 모듈에서 전송된 숫자가 나타나게 됩니다.




위 예제코드는 첨부파일로 올려두겠습니다^^

CC1101.zip

Panstamp.zip


위 코드는 CC1101에 해당하는 예제이고, Panstamp는 조금더 복잡한, RSSI, Data length, CRC 등등을 확인하는 함수들을 사용한답니다ㅎㅎ


Panstamp코드를 실행하면 아래와 같이 신호강도(RSSI), 데이터 길이, 패킷정보 등 다양하게 확인할 수 있고, 이 함수를 이용해 실질적으로 프로젝트에 사용할 수 있습니다.



이렇게 433mHz 무선통신 모듈의 사용법을 알아보았습니다^^


디테일한 설명들이 부족하긴 하지만, 궁금한점이 있으시면 댓글 남겨주세요~!


지난시간에 이어 이번시간에는 OLED모듈에 원하는 아이콘을 어떻게 그리는지에 대해 알아보도록 하겠습니다.


보통 한장의 사진을 컴퓨터에 저장할때 흔히들 사용하는 포멧이 .jpeg, .jpg, .png 등등 이러한 형태일텐데요~

대부분의 이미지들은 원본 데이터를 압축하여 저장을 하게 된답니다. 때문에 미세하게 보면 일그러지거나 왜곡되는 현상이 부분부분 나타나게 된답니다.


그렇다면 원본 데이터를 손상없이 저장하려면 어떻게 해야할까요? 바로 비트맵(Bitmap, ~.bmp) 형식의 파일입니다.


비트맵이란, 말 그대로 각각의 데이터(비트)를 일일이 매핑하여 나타내는 것으로, 압축되지않은, 픽셀단위의 데이터를 모두 보관하고 있는 이미지입니다.


왜 뜬금없이 비트맵을 설명했냐하면!!


보통의 LCD, LED 디스플레이의 경우, 하나 하나의 점(픽셀)을 이용해 글씨나 그림을 나타내는 방식으로, 이를 원하는 그림으로 바꾸기 위해서는 각각의 픽셀을 켜고, 끄는것을 통해 제어를 해야합니다.


간단히 예를 들어보면,


지난 포스팅의 마지막부분에 보여드렸던 

  B00000000, B11000000,

  B00000001, B11000000,

  B00000001, B11000000,

  B00000011, B11100000,

  B11110011, B11100000,

  B11111110, B11111000,

  B01111110, B11111111,

  B00110011, B10011111,

  B00011111, B11111100,

  B00001101, B01110000,

  B00011011, B10100000,

  B00111111, B11100000,

  B00111111, B11110000,

  B01111100, B11110000,

  B01110000, B01110000,

  B00000000, B00110000


이 데이터를 보면 대체 뭔가 싶기도 하시겠지만, 사실 이 자체가 하나의 그림을 나타내고 있답니다.


이를 좀더 그림같아 보이게 표에다가 넣어보면


위와 같이 나올텐데, 직관적으로 어떤 그림인지 감이 안오시죠?


그렇다면 1이된 부분만 색칠해보면(1이된 부분만 불이 켜지니깐요^^),



짜잔...! 엉성하긴 하지만 나름 별모양이지요? 

네 바로 Adafruit 회사의 로고모양입니다.


이번 시간에는 I2C 통신을 이용한 128x64 OLED 디스플레이 모듈 사용에 대해 배워보겠습니다.


먼저, I2C 통신을 하기 위해서는 장치의 Address를 알아야 하는데, 보통은 장치의 Spec sheet를 보면 나와있습니다.

만에 하나 Address를 모른다고 하면, 아래처럼 하드웨어를 연결하고 코드를 업로드 하시면 연결된 장치의 Address를 알 수 있습니다^^


 

 OLED모듈    아두이노

     VCC  ----  5V
     GND ---- GND

     SDA ---- SDA (A4)

     SCL  ---- SCL (A5)



  1. // --------------------------------------
  2. // i2c_scanner
  3. //
  4. // Version 1
  5. //    This program (or code that looks like it)
  6. //    can be found in many places.
  7. //    For example on the Arduino.cc forum.
  8. //    The original author is not know.
  9. // Version 2, Juni 2012, Using Arduino 1.0.1
  10. //     Adapted to be as simple as possible by Arduino.cc user Krodal
  11. // Version 3, Feb 26  2013
  12. //    V3 by louarnold
  13. // Version 4, March 3, 2013, Using Arduino 1.0.3
  14. //    by Arduino.cc user Krodal.
  15. //    Changes by louarnold removed.
  16. //    Scanning addresses changed from 0...127 to 1...119,
  17. //    according to the i2c scanner by Nick Gammon
  18. //    http://www.gammon.com.au/forum/?id=10896
  19. // Version 5, March 28, 2013
  20. //    As version 4, but address scans now to 127.
  21. //    A sensor seems to use address 120.
  22. // Version 6, November 27, 2015.
  23. //    Added waiting for the Leonardo serial communication.
  24. //
  25. //
  26. // This sketch tests the standard 7-bit addresses
  27. // Devices with higher bit address might not be seen properly.
  28. //
  29.  
  30. #include <Wire.h>
  31.  
  32.  
  33. void setup()
  34. {
  35.   Wire.begin();
  36.  
  37.   Serial.begin(9600);
  38.   while (!Serial);             // Leonardo: wait for serial monitor
  39.   Serial.println("\nI2C Scanner");
  40. }
  41.  
  42.  
  43. void loop()
  44. {
  45.   byte error, address;
  46.   int nDevices;
  47.  
  48.   Serial.println("Scanning...");
  49.  
  50.   nDevices = 0;
  51.   for(address = 1; address < 127; address++ )
  52.   {
  53.     // The i2c_scanner uses the return value of
  54.     // the Write.endTransmisstion to see if
  55.     // a device did acknowledge to the address.
  56.     Wire.beginTransmission(address);
  57.     error = Wire.endTransmission();
  58.  
  59.     if (error == 0)
  60.     {
  61.       Serial.print("I2C device found at address 0x");
  62.       if (address<16)
  63.         Serial.print("0");
  64.       Serial.print(address,HEX);
  65.       Serial.println("  !");
  66.  
  67.       nDevices++;
  68.     }
  69.     else if (error==4)
  70.     {
  71.       Serial.print("Unknow error at address 0x");
  72.       if (address<16)
  73.         Serial.print("0");
  74.       Serial.println(address,HEX);
  75.     }    
  76.   }
  77.   if (nDevices == 0)
  78.     Serial.println("No I2C devices found\n");
  79.   else
  80.     Serial.println("done\n");
  81.  
  82.   delay(5000);           // wait 5 seconds for next scan
  83. }



그리고 시리얼 모니터 창을 켜보시면 아래와 같이 Address가 나옵니다.



자 그럼 Address도 알았겠다, 본격적으로 시작을 해보겠습니다.


우선 필요한 라이브러리부터 다운받도록 하겠습니다.

1. https://github.com/adafruit/Adafruit_SSD1306 (Adafruit_SSD1306)

2. https://github.com/adafruit/Adafruit-GFX-Library (Adafruit-GFX-Library)


위 라이브러리들을 다운받으신 뒤, 아래 폴더에 압축을 푸시면 아두이노에서 라이브러리를 쓰실 수 있습니다.

C:\Users\(사용자 이름)\Documents\Arduino\libraries


자 이제 아두이노를 실행시켜서 예제를 먼저 업로드 해보겠습니다.



제대로 업로드가 되면 아래와 같은 영상이 OLED 디스플레이에 나타나게 됩니다^^






본 디스플레이 모듈에서 특정 이미지나 아이콘을 보여주고싶으시다면, 


static const unsigned char PROGMEM logo16_glcd_bmp[] =

{ B00000000, B11000000,

  B00000001, B11000000,

  B00000001, B11000000,

  B00000011, B11100000,

  B11110011, B11100000,

  B11111110, B11111000,

  B01111110, B11111111,

  B00110011, B10011111,

  B00011111, B11111100,

  B00001101, B01110000,

  B00011011, B10100000,

  B00111111, B11100000,

  B00111111, B11110000,

  B01111100, B11110000,

  B01110000, B01110000,

  B00000000, B00110000

};


위와같이 특정 변수들을 define해주셔야 합니다.


그럼 다음시간엔 어떻게 원하는 아이콘을 디스플레이 하는지 배워보도록 할게요ㅎㅎ

+ Recent posts