파이썬 아두이노 와이파이 통신 - paisseon adu-ino waipai tongsin

파이썬으로 와이파이를 다루기 위해 구글링을 하다보면 두 가지 모듈이 눈에 들어온다.

- wifi

- python-wifi

- python-networkmanager

- winwifi

- win32wifi

그런데 대부분 못 써먹는다.... 못 써먹는 이유는 아래와 같다. 

더보기

1. 먼저 wifi 모듈은 Linux를 위한 모듈이기 때문에 윈도우에서는 사용이 불가능하다. 

(오류 메시지: FileNotFoundError: [WinError 2] 지정된 파일을 찾을 수 없습니다)

참고글: stackoverflow.com/questions/38846295/python3-wifi-library-does-not-run-with-cell-allwlan0/38846996

2. 다음으로 python-wifi 모듈은 잘은 모르겠지만 python 2를 기반으로 만들어진 모듈이라 python 3으로 넘어오면서

except 관련한 문법이 바뀌면서 Syntax 에러가 잡혀 일반적으로 사용할 수가 없다.

python-wifi 패키지의 문법 오류를 다 수정하면 작동할지도 모르겠으나 편하게 쓰려고 패키지를 사용하는 것인데

일일이 고칠꺼면 차라리 내 입맛에 맞게 새로 작성하는 게 나을 거 같다.

3. python-networkmanager는 pip으로 설치가 안 된다 -_-

(오류 메시지: Building wheel for dbus-python (setup.py) ... error ERROR: Command errored out with exit status 1:)

git으로 수동 설치를 해야하는 거 같은데 귀찮다........

4. winwifi는 모듈이 아니라 CLI이다. python에서 사용하는 것이 아니라 cmd 창에서 사용하는 것이다. 이거라도 사용해볼까 싶었지만 wifi scan 해보니 한글이 뷅쉝으로 변해있다. 고치기 귀찮다......

5. cmd 기본 명령어

- netsh wlan connect ssid name interface 명령어를 통해 특정 와이파이 연결이 가능하다 (기존 등록된 와이파이만 가능)

6. 이 중 써먹을 수 있는 패키지는 바로 win32wifi 이다.

자세한 설명은 github.com/kedos/win32wifi 에서 참조하자.

그래서 그나마 쓸만한 패키지인 win32wifi를 기반으로 새로운 모듈을 작성하였다.

pypi.org/project/ezwifi/

ezwifi

Easy Python WiFi package for windows (Based on win32wifi package)

pypi.org

파이썬 아두이노 와이파이 통신 - paisseon adu-ino waipai tongsin

설치방법: pip install ezwifi==1.0.0.11 

사용 예시는 아래에 적어두겠다. (1.0.0.11 버전 기준)

1. WiFi 검색 결과 보기

# pip install ezwifi

import ezwifi

w = ezwifi.Wifi()
w.show_list()

2 WiFi 검색 결과 가져오기

# pip install ezwifi

import ezwifi

w = ezwifi.Wifi()
wifiList = w.get_list()
print(wifiList)

3. WiFi 연결하기

# pip install ezwifi

import ezwifi

w = ezwifi.Wifi()
w.connect("ssid", "pass")

# w.connect("ssid") 
# 비밀번호가 없거나 이전에 접속한 적 있는 와이파이의 경우 pass 생략 가능

# w.connect("ssid", mode = "auto")
# 자동 연결 설정

4. WiFi 연결끊기

# pip install ezwifi

import ezwifi

w = ezwifi.Wifi()
w.disconnect()

5. WiFi 검색 리스트 갱신

# pip install ezwifi

import ezwifi

w = ezwifi.Wifi()
w.scan()
# w.show_list()

* 대표이미지 *

파이썬 아두이노 와이파이 통신 - paisseon adu-ino waipai tongsin

예전 PLC와 컴퓨터 python을 연결할 때 아두이노로 대신 테스트 했다.

아두이노가 PLC역할을 하고,

Python은 PC로 돌리게 된다.

컴퓨터와 아두이노간의 연결하는 코드이다.

아두이노에 스위치를 달고 LED를 달고 테스트

아두이노의 시리얼 포트로 115200 비트로 통신한다.

아두이노에서 ready신호를 보내면, PC의 python코드가 작동하고

PC에서 1번 (합격), 2번 (불합격) 신호를 보내면

아두이노에서 그에 맞는 동작을 하는 코드이다.

아두이노 코드

const int buttonPin1 = 8;      //  8 번핀 스위치 입력 테스트 (PLC의 ready신호)
char LEDpin1 = 12;    //  OK LED 포트 설정
char LEDpin2 = 13;    //  NG

int flag = 0;
int NGflag = 0;
int OKflag = 0;

// LED확인용 함수.
void OK(void)
{
    digitalWrite(LEDpin1, HIGH);
    digitalWrite(LEDpin2, LOW);
}
void NG(void)
{
    digitalWrite(LEDpin2, HIGH);
    digitalWrite(LEDpin1, LOW);
}


void setup() {
  Serial.begin(115200);              //  시리얼 통신의 시작, 보레이트 입력
  pinMode(buttonPin1, INPUT_PULLUP);  //  스위치 내부풀업저항 입력포트로 셋팅.
  
  pinMode(LEDpin1, OUTPUT);           //  OK, NG LED 출력포트 지정.
  pinMode(LEDpin2, OUTPUT);
}

void loop() {
  char c = Serial.read();           //  PC로부터온 값을 읽음.
  int buttonValue1 = digitalRead(8); //  8번 핀에서 읽음.
  
  if(buttonValue1 == LOW )           //  스위치가 눌릴때 ready신호를 보냄. (PLC -> PC)
  {
    flag = 1;
  }
  if(flag == 1)
  {
      Serial.println("ready");      //  준비가 되었다고 PC에 신호를 보냄.
      delay(500);
      flag = 0;
  }

  // 아스키코드 0x31 들어올때, OK
  if( c == '1')
  {
      OKflag = 1;
  }

  // 아스키코드 0x32 들어올때, NG
  else if( c == '2')
  {
      NGflag = 1;
  }

  

  if(OKflag == 1)
  {
    OK();
    OKflag = 0;
  }
  if(NGflag == 1)
  {
    NG();
    NGflag = 0;
  }

}

파이썬 코드

import serial

ser = serial.Serial(
    port='COM3',
    baudrate=115200,
    parity=serial.PARITY_NONE,\
    stopbits=serial.STOPBITS_ONE,\
    bytesize=serial.EIGHTBITS,\
)


while True:
    if ser.readable():
        res = ser.readline()                 # 시리얼로 날라온 bytes 값이 저장됨.
        ready = res.decode()[:len(res)-2]    # bytes를 decode 해서 str로 변환, 자동으로 포함되어있는 개행을 제거하기 위해 [:len(res)-2] 를 추가함 : 즉, \r\n 을 제거함.

        print(ready)        # 아두이노(PLC)에서 날라온 프로토콜.

        judge = input()             # 유저가 입력 '1' 또는 '2' 테스트 하기 위해.

        OK = chr(0x31)              # '1' 일때 OK
        NG = chr(0x32)              # '2' 일때 NG

        # 프로토콜을 받고 판독 시작.
        if ready == 'ready':
            if judge == OK:

                OK = OK.encode()     # OK일때 char 를 bytes로 인코딩
                ser.write(OK)        # 아스키코드 0x31 전송

            elif judge == NG:

                NG = NG.encode()     # NG일때 아스키코드 0x32 전송
                ser.write(NG)
            else:
                pass