1. Adapter Board

 

시판되는 DWM1000 모듈은 SMD용으로써 SMD레벨 PCB제작시에는 바로 사용할 수 있지만 전극 사이가 좁아 수작업으로 제작하여 테스트하기에는 매우 불편하다. 따라서 테스트나 프로토타입 개발단계에서는 다음과 같은 Adapter Board에 모듈을 납땜하여 브레드보느나 만능기판에 연결하여 사용한다. 

 

Adater Board의 핀배열은 원래 칩의 핀배열과는 다소 다르게 구성된다.  

 

 

2. MCU 연결 

 

DWM1000은 통신모듈이기 때문에 특정 기능을 작동시키기 위에서는 Porcessor가 필요한데 DWM1000모듈이 3.3V 기반이고 SPI 방식으로 Processor와 통신하므로 이에 적합한 MCU가 필요하다. 따라서 아두이노 프로미니3.3V형, ESP8266/ ESP32 등 ESP시리즈, STM32 모듈 등을 사용하는데 여기에서는ESP32를 사용해 본다.    

 

 

DWM1000 모듈핀  ESP32 PIN
CLK D18
MISO D19
MOSI D23
CSN  D2
VCC 3.3V
GND GND
RESET D15
IRQ D5

 

여기에서 CLK, MISO, MOSI 핀은 ESP32에서 SPI통신을 위해 고정되어 있는 핀으로 반드시 여기에 연결해야 하지만 나머지는 기능 제어를 위한 핀이으로 다른 핀으로 대체할 수 있다. 

 

3. Library설치 

 

DWM000 모듈을 사용하기 위한 Library는 여러가지가 있지만 여기에서는 다음 라이브러리를 사용한다.

 

 

GitHub - F-Army/arduino-dw1000-ng: Arduino driver and library to use Decawave's DW1000 IC and relative modules.

Arduino driver and library to use Decawave's DW1000 IC and relative modules. - GitHub - F-Army/arduino-dw1000-ng: Arduino driver and library to use Decawave's DW1000 IC and relative modules.

github.com

여기에는 몇가지 샘플프로그램이 포함되어 있어 즉시 테스트해 볼 수 있다.  

4. 샘플프로그램 

4-1 송신프로그램 

 

#include <DW1000Ng.hpp>
/*
#if defined(ESP8266)
//const uint8_t PIN_RST = 5; // reset pin
//const uint8_t PIN_IRQ = 4; // irq pin
const uint8_t PIN_SS = 15; // spi select pin
#else
//const uint8_t PIN_RST = 9; // reset pin
//const uint8_t PIN_IRQ = 2; // irq pin
const uint8_t PIN_SS = SS; // spi select pin
#endif
*/
const uint8_t PIN_SCK = 18;  
const uint8_t PIN_MOSI = 23; 
const uint8_t PIN_MISO = 19;  
const uint8_t PIN_SS = 2;  
const uint8_t PIN_RST = 15;  
const uint8_t PIN_IRQ = 5;  

// DEBUG packet sent status and count
volatile unsigned long delaySent = 0;
int16_t sentNum = 0; // todo check int type

device_configuration_t DEFAULT_CONFIG = {
    false,
    true,
    true,
    true,
    false,
    SFDMode::STANDARD_SFD,
    Channel::CHANNEL_5,
    DataRate::RATE_850KBPS,
    PulseFrequency::FREQ_16MHZ,
    PreambleLength::LEN_256,
    PreambleCode::CODE_3
};

void setup() {
  // DEBUG monitoring
  Serial.begin(9600);
  Serial.println(F("### DW1000Ng-arduino-sender-test ###"));
  // initialize the driver
  DW1000Ng::initializeNoInterrupt(PIN_SS);
  Serial.println(F("DW1000Ng initialized ..."));

  DW1000Ng::applyConfiguration(DEFAULT_CONFIG);
	//DW1000Ng::applyInterruptConfiguration(DEFAULT_INTERRUPT_CONFIG);

  DW1000Ng::setDeviceAddress(5);
  DW1000Ng::setNetworkId(10);

  DW1000Ng::setAntennaDelay(16436);
  Serial.println(F("Committed configuration ..."));
  // DEBUG chip info and registers pretty printed
  char msg[128];
  DW1000Ng::getPrintableDeviceIdentifier(msg);
  Serial.print("Device ID: "); Serial.println(msg);
  DW1000Ng::getPrintableExtendedUniqueIdentifier(msg);
  Serial.print("Unique ID: "); Serial.println(msg);
  DW1000Ng::getPrintableNetworkIdAndShortAddress(msg);
  Serial.print("Network ID & Device Address: "); Serial.println(msg);
  DW1000Ng::getPrintableDeviceMode(msg);
  Serial.print("Device mode: "); Serial.println(msg);
  // attach callback for (successfully) sent messages
  //DW1000Ng::attachSentHandler(handleSent);
  // start a transmission
  transmit();
}

/*
void handleSent() {
  // status change on sent success
  sentAck = true;
}
*/

void transmit() {
  // transmit some data
  Serial.print("Transmitting packet ... #"); Serial.println(sentNum);
  String msg = "Hello DW1000Ng, it's #"; msg += sentNum;
  DW1000Ng::setTransmitData(msg);
  // delay sending the message for the given amount
  delay(100);
  DW1000Ng::startTransmit(TransmitMode::IMMEDIATE);
  delaySent = millis();
  while(!DW1000Ng::isTransmitDone()) {
    #if defined(ESP8266)
    yield();
    #endif
  }
  sentNum++;
  DW1000Ng::clearTransmitStatus();
}

void loop() {
    transmit();
    // update and print some information about the sent message
    Serial.print("ARDUINO delay sent [ms] ... "); Serial.println(millis() - delaySent);
    uint64_t newSentTime = DW1000Ng::getTransmitTimestamp();
    Serial.print("Processed packet ... #"); Serial.println(sentNum);
}

 

4-2 수신프로그램 

 

#include <DW1000Ng.hpp>
/*
#if defined(ESP8266)
//const uint8_t PIN_RST = 5; // reset pin
//const uint8_t PIN_IRQ = 4; // irq pin
const uint8_t PIN_SS = 15; // spi select pin
#else
//const uint8_t PIN_RST = 9; // reset pin
//const uint8_t PIN_IRQ = 2; // irq pin
const uint8_t PIN_SS = SS; // spi select pin
#endif
*/
const uint8_t PIN_SCK = 18;  
const uint8_t PIN_MOSI = 23; 
const uint8_t PIN_MISO = 19;  
const uint8_t PIN_SS = 2;  
const uint8_t PIN_RST = 15;  
const uint8_t PIN_IRQ = 5;  
int16_t numReceived = 0; // todo check int type
String message;

device_configuration_t DEFAULT_CONFIG = {
    false,
    true,
    true,
    true,
    false,
    SFDMode::STANDARD_SFD,
    Channel::CHANNEL_5,
    DataRate::RATE_850KBPS,
    PulseFrequency::FREQ_16MHZ,
    PreambleLength::LEN_256,
    PreambleCode::CODE_3
};

void setup() {
  // DEBUG monitoring
  Serial.begin(9600);
  Serial.println(F("### DW1000Ng-arduino-receiver-test ###"));
  // initialize the driver
  DW1000Ng::initializeNoInterrupt(PIN_SS);
  Serial.println(F("DW1000Ng initialized ..."));

  DW1000Ng::applyConfiguration(DEFAULT_CONFIG);

  DW1000Ng::setDeviceAddress(6);
  DW1000Ng::setNetworkId(10);

  DW1000Ng::setAntennaDelay(16436);
  Serial.println(F("Committed configuration ..."));
  // DEBUG chip info and registers pretty printed
  char msg[128];
  DW1000Ng::getPrintableDeviceIdentifier(msg);
  Serial.print("Device ID: "); Serial.println(msg);
  DW1000Ng::getPrintableExtendedUniqueIdentifier(msg);
  Serial.print("Unique ID: "); Serial.println(msg);
  DW1000Ng::getPrintableNetworkIdAndShortAddress(msg);
  Serial.print("Network ID & Device Address: "); Serial.println(msg);
  DW1000Ng::getPrintableDeviceMode(msg);
  Serial.print("Device mode: "); Serial.println(msg);
}

void loop() {
  DW1000Ng::startReceive();
  while(!DW1000Ng::isReceiveDone()) {
//    #if defined(ESP8266)
    yield();
//    #endif
  }
  DW1000Ng::clearReceiveStatus();
  numReceived++;
  // get data as string
  DW1000Ng::getReceivedData(message);
  Serial.print("Received message ... #"); Serial.println(numReceived);
  Serial.print("Data is ... "); Serial.println(message);
  Serial.print("RX power is [dBm] ... "); Serial.println(DW1000Ng::getReceivePower());
  Serial.print("Signal quality is ... "); Serial.println(DW1000Ng::getReceiveQuality());
}

 

+ Recent posts