728x90
반응형
#include <Servo.h>

const int SERVO = 9;
Servo servo;

void setup()
{
  Serial.begin(9600);
  servo.attach(SERVO);

  for (int angle = 0; angle < 180; angle++)
  {
    servo.write(angle);
    delay(20);
  }

  servo.write(0);
}

void loop()
{
  /* 서보 모터의 명령을 파악 */
  // 숫자로 이루어진 문자열 cmd <-
  String cmd = serialRead();
  // cmd 는 "" 값을 기본으로 한다.

  if (cmd == "")
  {
    return;
  }

  int angle = cmd.toInt();

  /* 명령에 따른 동작 */
  // int angle = 0;
  servo.write(angle);
  delay(200);

  /* 처리된 결과를 출력 */
  serialWrite(cmd);
  

  // 해당 처리를 한 루프 1번 반복에 대략 2초 가량 소요된다고 가정
}

String serialRead()
{
  String str = "";

  // while(true)
  // {
  //   char c = Serial.read();
  //   if (c == '\0')
  //   {
  //     break;
  //   }
  //   str.concat(c);
  // }


  // 읽어올것이 있을 때 True
  while(Serial.available())
  {
    char c = Serial.read();
    // String c = Serial.readString();
    str.concat(c);
    delay(5);
  }

  return str;
}

void serialWrite(String str)
{
  // 비어있거나 NULL인 문자열은 통신금지 return
  if (str == NULL || str.length() <= 0)
  {
    return;
  }

  // {'h', 'e', 'l', 'l', 'o', '\0'};

  for (int i = 0; i < str.length(); i++)
  {
    // 한글자씩 받아서 붙이는 (방법1)
    // 필요성에 따라 방법이 다름
    Serial.print(str.charAt(i));
  }
  // print는 문자열 단위로 나감.
  // Serial.print(str); // (방법2)줄내림이 newline 이 아닌 carage return 일수도 있음 \r
  // Serial.write(); // (방법3)64 를 넣으면 아스키코드 아마 A가 나갈거임 byte 단위로 나감
  // 만약 이미지 전송이라면 byte 단위로 보내야 하기 때문에 write
  // 정수 단위 바이너리가 전송됨
  // 파이썬은 어차피 무엇을 보내도 byte로 읽어들여옴.
  Serial.print('\n'); // 줄내림을 기준
}
import serial
import os
import time
import threading

PORT = "COM8"
BAUDRATE = 9600
# ser = serial.Serial(PORT, baudrate=BAUDRATE)

ser:serial.Serial = None

def prepare():
    global ser
    
    ser = serial.Serial(PORT, baudrate=BAUDRATE)
    
    #Generate thread object
    #target 쓰레드가 수행할 처리가 담긴 함수
    # t = threading.Thread(target = sum, args=(1, 100000000))
    t = threading.Thread(target = readSerial)
    t.daemon = True # main Thread 죽으면 같이 따라 종료(중요!)
    t.start() # Thread 시작
    
    pass

def readSerial():
    
    while True:
        line = ser.readline().decode().replace('\n', '').replace('\r', '')
        
        if not line:
            # time.sleep(1)
            continue
        
        print("readline: " + line)
        pass
    
    pass

# Command set is string, not byte
def writeSerial():
    
    while True:
        
        os.system('cls')
        #input 이 해당 함수의 매개변수를 대신해주고 있음
        msg = input('각도를 입력하세요 (0-180) 종료: q: \n')
        
        if msg == 'q':
            break
        
        # 정수가 아니라면 continue로 다시 처음으로 이동
        # - 마이너스 일시 -1 또한 문자열로 처리되어 lstrip으로 부호 삭제
        if not msg.lstrip('-').isdigit():
        # if not msg.isnumeric():
            print('숫자가 아닙니다')
            continue
        
        angle = int(msg) # 정수값으로 형변환 지정
        
        # or, and 조건인지 확인
        if 0 > angle or angle > 180:
            print('유효 범위를 벗어나 다시 입력')
            time.sleep(2)
            continue
        
        # encode를 하려면 숫자지만 문자열이어야함 다시 형변환
        ser.write(str(angle).encode())
        print('정상적으로 전송되었습니다: ', angle)
        
        time.sleep(2)
        
        # line = ser.readline().decode().replace('\n', '').replace('\r', '')
        # print("받아온 값: ", line)
        # time.sleep(2)
        
        pass
    
    pass

# Thread Test code
def sum(row, high):
    while True:
    
        total = 0
        for i in range(row, high):
            total += i
        print('sum: ', total)
        
    pass


if __name__ == '__main__':
    prepare()
    
    # 블럭 : 사용자 입력 계속해서 받음, 함수 내 while문, 탈출조건또한 있음
    writeSerial()
    
    
    
    
    pass
728x90
반응형

'Qt' 카테고리의 다른 글

login  (0) 2022.11.04
QPushbutton exam..  (0) 2022.11.03
[Qt] Login.py _linux  (0) 2022.11.03
Python Serial Write Qt  (0) 2022.11.01
qt_groupbox_frame.py  (0) 2022.10.28

+ Recent posts