2019년 6월 18일 화요일

LTE modem 사용

LTE modem 모델은 Huawei E8372h-153


aliexpress에서 $30~40에 구할 수 있다. 워낙 많은 통신사에서 사용하는 모델이다 보니 제품 윗면의 로고는 다를 수 있는데 신경 쓸 필요 없음






 뒷면에보면 모델명을 확인할 수 있음


기본적으로 내부에 안테나가 들어있어 그대로 사용해도 되지만 신호 수신을 좋게하기 위해 옆면에 외부 안테나를 부착할 수 있는 포트가 마개로 덮혀 있음



이런식으로 외부 안테나 부착이 가능함


로고가 표시돠어 있는 윗면을 커넥터 반대쪽으로 살짝 밀면 뚜껑이 간단하게 분리된다. 내부에 위의 사진과 같이 MicroSD와 SIM card를 꼽을 수 있는 커넥터가 있다. SIM카드를 삽입하고 뚜껑을 덮어주면 됨

통신망은 LG U+의 LTE를 사용.

전원을 연결하면 잠시 후 제일 왼쪽 LED가 초록색으로 점멸하기 시작


무선랜을 선택해 LTE모뎀에 접속 (SSID, WiFi key는 뚜껑을 열어보면 확인할 수 있음. 장치 홈페이지에서 관리자 ID/PW는 둘 다 admin/admin 

맨 처음 연결하면 프로파일을 만들어 줘야 함. LG U+ LTE이므로 프로파일 이름은 임의로 설정, ID/PW는 없음, APN은 internet.lguplus.co.kr 을 넣어주면 됨

정상적으로 설정이 끝나 통신망에 접속하면 제일 왼쪽 LED가 푸른색으로 켜져 있음

제일 오른쪽 LED는 무선랜 상태를 표시. 녹색으로 켜져 있음 정상 동작하는 것임

* 이 방식의 장점은 LTE 데이터를 여러 장비에서 공유가 가능. 또한 USB를 꼭 컴퓨터가 아니고 휴대폰 충전기나 휴대용 배터리에 연결해서 사용할 수 있음
 

2019년 6월 14일 금요일

ESP32에서 CAN bus 사용하기

CAN버스는 Controller Area Network를 말하는데 이 프로토콜은 주로 자동차에서 널리 이용되고 있다. CAN에 대해 더 자세히 알고 싶으면 다음의 링크들을 참고하면 된다.

- http://www.ni.com/white-paper/2732/en
- http://www.ti.com/lit/an/sloa101b/sloa101b.pdf

ESP32는 CAN 인터페이스를 지원하기 때문에 CAN bus를 쉽게 사용할 수 있다.
이 데모에서는 2개의 ESP32 모듈을 사용해, 첫번째 모듈은 'hellocan' 이라는 메시지를 보내고 두번째 모듈은 받은 메시지의 문자열을 전부 대문자로 바꿔 첫번째 모듈로 돌려보낸다. 그러면 첫번째 모듈은 받은 메시지를 터미널로 출력하게 된다.

ESP32는 CAN controller만을 내장하고 있기 때문에 CAN 버스를 사용하려면 CAN transceiver가 필요하다. 아래 사진의 CAN transceiver를 2개 사용했다.

* aliexpress에서 개당 약 $1 정도로 구입할 수 있다.

ESP32와 CAN transceiver 모듈의 연결은 다음과 같이 해 주면 된다.


CAN library로는 Thomas Barth가 만든 CAN driver를 사용했다.

https://github.com/ThomasBarth/ESP32-CAN-Driver/tree/master/components/can

라이브러리를 다운받아 설치해주면 된다.

첫번째 ESP32 (위의 그림에서 ESP32 (1)에 해당)에는 아래와 같은 코드를 넣어준다.

#include <ESP32CAN.h>
#include <CAN_config.h>

/* the variable name CAN_cfg is fixed, do not change */
CAN_device_t CAN_cfg;

void setup() {
    Serial.begin(115200);
    Serial.println("iotsharing.com CAN demo");
    /* set CAN pins and baudrate */
    CAN_cfg.speed=CAN_SPEED_1000KBPS;
    CAN_cfg.tx_pin_id = GPIO_NUM_5;
    CAN_cfg.rx_pin_id = GPIO_NUM_4;
    /* create a queue for CAN receiving */
    CAN_cfg.rx_queue = xQueueCreate(10,sizeof(CAN_frame_t));
    //initialize CAN Module
    ESP32Can.CANInit();
}

void loop() {
    CAN_frame_t rx_frame;
    //receive next CAN frame from queue
    if(xQueueReceive(CAN_cfg.rx_queue,&rx_frame, 3*portTICK_PERIOD_MS)==pdTRUE){

      //do stuff!
      if(rx_frame.FIR.B.FF==CAN_frame_std)
        printf("New standard frame");
      else
        printf("New extended frame");

      if(rx_frame.FIR.B.RTR==CAN_RTR)
        printf(" RTR from 0x%08x, DLC %d\r\n",rx_frame.MsgID,  rx_frame.FIR.B.DLC);
      else{
        printf(" from 0x%08x, DLC %d\n",rx_frame.MsgID,  rx_frame.FIR.B.DLC);
        /* convert to upper case and respond to sender */
        for(int i = 0; i < 8; i++){
          if(rx_frame.data.u8[i] >= 'a' && rx_frame.data.u8[i] <= 'z'){
            rx_frame.data.u8[i] = rx_frame.data.u8[i] - 32;
          }
        }
      }
      //respond to sender
      ESP32Can.CANWriteFrame(&rx_frame);
    }
}

두번째 ESP32 (위의 그림에서 ESP32 (2)에 해당)에는 아래와 같은 코드를 넣어준다.

#include <ESP32CAN.h>
#include <CAN_config.h>

/* the variable name CAN_cfg is fixed, do not change */
CAN_device_t CAN_cfg;

void setup() {
    Serial.begin(115200);
    Serial.println("iotsharing.com CAN demo");
    /* set CAN pins and baudrate */
    CAN_cfg.speed=CAN_SPEED_1000KBPS;
    CAN_cfg.tx_pin_id = GPIO_NUM_5;
    CAN_cfg.rx_pin_id = GPIO_NUM_4;
    /* create a queue for CAN receiving */
    CAN_cfg.rx_queue = xQueueCreate(10,sizeof(CAN_frame_t));
    //initialize CAN Module
    ESP32Can.CANInit();
}

void loop() {
    CAN_frame_t rx_frame;
    //receive next CAN frame from queue
    if(xQueueReceive(CAN_cfg.rx_queue,&rx_frame, 3*portTICK_PERIOD_MS)==pdTRUE){

      //do stuff!
      if(rx_frame.FIR.B.FF==CAN_frame_std)
        printf("New standard frame");
      else
        printf("New extended frame");

      if(rx_frame.FIR.B.RTR==CAN_RTR)
        printf(" RTR from 0x%08x, DLC %d\r\n",rx_frame.MsgID,  rx_frame.FIR.B.DLC);
      else{
        printf(" from 0x%08x, DLC %d\n",rx_frame.MsgID,  rx_frame.FIR.B.DLC);
        for(int i = 0; i < 8; i++){
          printf("%c\t", (char)rx_frame.data.u8[i]);
        }
        printf("\n");
      }
    }
    else
    {
      rx_frame.FIR.B.FF = CAN_frame_std;
      rx_frame.MsgID = 1;
      rx_frame.FIR.B.DLC = 8;
      rx_frame.data.u8[0] = 'h';
      rx_frame.data.u8[1] = 'e';
      rx_frame.data.u8[2] = 'l';
      rx_frame.data.u8[3] = 'l';
      rx_frame.data.u8[4] = 'o';
      rx_frame.data.u8[5] = 'c';
      rx_frame.data.u8[6] = 'a';
      rx_frame.data.u8[7] = 'n';

      
      ESP32Can.CANWriteFrame(&rx_frame);
    }
}

양쪽의 보드를 동작시키고 첫번째 ESP32의 시리얼 터미널의 출력은 다음과 같다.




* Original credit goes to http://www.iotsharing.com/2017/09/how-to-use-arduino-esp32-can-interface.html