2017-11-01 1 views
-2

나는 relaisboard를 Python 바인딩을 사용하는 firmata 프로토콜을 통해 arduino에 연결했습니다. 의사 소통은 문제없이 pyfirmata (https://github.com/tino/pyFirmata)를 사용합니다.Python의 클래스 계층

relaisboard에는 16 개의 릴레이가 있습니다. 3 relais의 모든 그룹은 채널입니다. 모든 채널은 테스트중인 장치 입력 또는 출력에 연결됩니다. 이것은 단지 releboard의 목적에 대한 대략적인 설명을 가지고 있습니다.

아래에서 코드의 골격을 찾을 수 있습니다.

  • FaultInsertionBoardFirmata에서 Arduino 클래스의 래퍼입니다 :

    #!/usr/bin/env python 
    
    __version__ = '0.1' 
    
    # Fault Injection Unit 
    
    # Power is connected to Fault Bus 1 
    # Ground is connected to Fault Bus 2 
    
    from pyfirmata import Arduino 
    
    class FaultInsertionBoard(object): 
    
        def __init__ (self, comPort = 'COM3'): 
         """Initalize the Fault insertion Board 
    
         Open communication with host via serial port 
    
         Arguments: 
         comPort -- The serial port used to connect the board to the host. 
         """ 
         self.board = Arduino(comPort) 
    
        class Channel(object): 
    
         def __init__ (self, aChannel): 
          """ Create a Channel""" 
          pass 
    
         def NoFault(): 
          """ Set the channel to the "No fault" condition 
    
          No Fault condition is: 
          -- DUT channel connected to the testing sistem 
          -- DUT channel disconnected from the Fault bus 1 
          -- DUT channel disconnected from the Fault bus 2 
          """ 
          pass 
    
    
         def OpenCircuit(): 
          """ Set the channel to the "Open Circuit fault" condition 
    
          Open Circuit fault condition is: 
          -- DUT channel disconnected from the testing sistem 
          -- DUT channel disconnected from the Fault bus 1 
          -- DUT channel disconnected from the Fault bus 2 
          """ 
          pass 
    
         def ShortToGround(): 
          """ Set the channel to the "Short to Ground fault" condition 
    
          Open Circuit fault condition is: 
          -- DUT channel disconnected from the testing sistem 
          -- DUT channel disconnected from the Fault bus 1 
          -- DUT channel connected to the Fault bus 2 
          """ 
          pass 
    
         def ShortToPower(): 
          """ Set the channel to the "Short to Ground fault" condition 
    
          Open Circuit fault condition is: 
          -- DUT channel disconnected from the testing sistem: channel relay is open 
          -- DUT channel connected to the Fault bus 1: Fault Bus 1 relay is closed 
          -- DUT channel disconnected from the Fault bus 2: Fault Bus 1 relay is open 
          """ 
          pass 
    
    def main(): 
    
        FaultBoard = FaultInsertionBoard('COM3') 
        VoutSensor = FaultBoard.Channel(0) 
        IOutSensor = FaultBoard.Channel(1)  
        VoutSensor.NoFault() 
        IOutSensor.NoFault() 
        VoutSensor.ShortToGround() 
        IOutSensor.ShortToPower() 
    
    if __name__ == "__main__": 
        main() 
    

    .

  • Channel(n) 세 릴레
  • NoFault
  • , ShortToPower, ShortToGround 각 채널의 세 릴레 (이것은 실제 구성을 중요하지 않다)의 다양한 구성이다의 n 번째 그룹을 식별한다.

이제 질문 : 나는 C로 작성된 내장 된 펌웨어에 대해 아주 좋은 경험이 있으며, 파이썬에서는 훨씬 적다. 분명히 위의 코드는 올바르지 않습니다.

누가 위의 기능을 사용하기 위해 클래스 프레임 워크를 제안 할 수 있습니까? 다시 말해, 위에 설명 된대로 relais를 구동하기 위해 Python 코드를 작성하려면 어떻게해야합니까?

PS : 또는 나는 이런 식으로 뭔가 작성할 수

FaultBoard = FaultInsertionBoard('COM3') 
FaultBoard.Channel(0).NoFault() 

을하지만 덜 우아하고 분명하다 생각합니다.

+0

; 어떻게 도움을 얻을 것으로 기대합니까? –

+1

게시 한 코드가 작동하지 않습니까? –

+0

죄송합니다. 내 잘못입니다. 코드를 넣은 것 같습니다. 위의 편집 된 질문을 참조하십시오. –

답변

0

한편으로는 귀하의 실제 질문은 매우 일반적이며, 앞으로 더 구체적으로하려고 노력해야합니다. 반면에 초보자는 어디서부터 시작해야하는지 알기가 어렵 기 때문에이 도전을 극복하는 데 도움이되는 몇 가지 디자인 팁을 제공 할 것입니다.

없음 중첩 된 클래스

상자의 클래스는 거의 쓸모가 파이썬 없습니다. 완벽하게 합법적이지만 무의미합니다. 그것들은 당신을 포함하는 클래스에 대한 마법의 액세스를 제공하지는 않으며 (Java로있을 수 있기 때문에) 어떤 인스턴스에도 존재하지 않습니다. 중첩이하는 일은 네임 스페이스를보다 복잡하게 만드는 것입니다.

내가 할 첫 번째 일은 을 FaultInsertionBoard 밖으로 이동하는 것입니다. 간단한 문장만으로 충분합니다. 좀 더 사용 방법을 알려 드리겠습니다. 염두에 두어야 할 규칙을

또 다른 일을 명명

파이썬 명명 규칙입니다. 요구 사항은 아니지만 클래스 이름 만 대문자로 표기하는 것이 일반적이며, 그 밖의 모든 것은 소문자이며 단어 사이에는 밑줄이 붙습니다 (camelCase 대신).

함수 매개 변수에 대한 기본값 정의에 = 주위에 공백을 두는 것은 일반적으로 이 아니며이 아닙니다.

나는이 답변을 통해 이러한 규칙을 따를 것입니다. 봉쇄

당신은 아마 FaultInsertionBoard에 대한 상속보다는 봉쇄를 사용해야 대

의 Inheritance :

class FaultInsertionBoard(Arduino): 
    pass 

FaultInsertionBoard 모든 방법과 Arduino의 특성을 가지고 있는지 확인합니다. 이제 fault_board.board.method() 대신 fault_board.method()을 수행 할 수 있습니다. methodArduino 클래스의 일부 메소드입니다.

com_port의 기본값을 설정하고 나중에 채널을 설정하는 것과 같은 몇 가지 추가 초기화 단계를 정의해야 할 수 있습니다. 당신은 당신이 원하는 때마다 부모 클래스의 구현을 __init__의 자신의 버전을 정의하고 호출 할 수 있습니다 : 당신은 파이썬 2.X를 사용하는 경우, super(FaultInsertionBoard, self).__init__를 사용

class FaultInsertionBoard(Arduino): 
    def __init__(self, com_port='COM3'): 
     super().__init__(com_port) 

.

추가 채널

실제로 채널 인스턴스에 액세스 할 수 있으려면, 당신은 그들을 잡아 일부 데이터 구조를 정의하고, 앞까지 일부 채널을 초기화 할 필요가있다. 데이터 구조는 속성으로 직접 액세스하거나 매개 변수를 추가로 확인하는 메소드를 통해 액세스 할 수 있습니다.

앞서 언급했듯이 Channel 클래스를 중첩하면이 방향으로 이동하지 않습니다. 당신의 Channel 클래스는 아마도 부모 보드에 액세스해야하기 때문에 사실, 우리는 생성자에 새로운 초기화 매개 변수를 추가합니다 :

class Channel: 
    def __init__(self, channel_id, parent): 
     self.id = channel_id 
     self.parent = parent 

당신은 당신에게 사용할 수있는 옵션 몇 가지있다. 과 같이 표시됩니다 이제 main

class FaultInsertionBoard(Arduino): 
    def __init__(self, com_port='COM3'): 
     super().__init__(com_port) 
     self.channels = [] 
     self.channels.append(Channel(0, self)) 
     self.channels.append(Channel(1, self)) 
     ... 

: : 간단한 당신이 [] 오히려 ()보다 통해 액세스 할 수있는, FaultInsertionBoardChannel s의 순서를 초기화하는 것입니다

def main(): 
    fault_board = FaultInsertionBoard('COM3') 
    v_out_sensor = fault_board.channels[0] 
    i_out_sensor = fault_board.channel[1] 
    v_out_sensor.no_fault() 
    v_out_sensor.short_to_ground() 
    i_out_sensor.no_fault() 
    i_out_sensor.short_to_ground() 

당신이 절대적으로 사용하려는 경우 괄호를 사용하여 channel(0) 등으로 채널에 액세스하려면 FaultInsertionBoard에 메소드를 정의 할 수 있습니다. 과 같이 표시됩니다이 경우 main에서

def channel(self, index): 
    # Check index if you want to, possibly raise an error if invalid 
    return self.channels[index] 

: 동일 __init__ 방법을 유지, 당신은 다른 방법을 추가 할 수 있습니다

def main(): 
    fault_board = FaultInsertionBoard('COM3') 
    v_out_sensor = fault_board.channel(0) 
    i_out_sensor = fault_board.channel(1) 
    v_out_sensor.no_fault() 
    v_out_sensor.short_to_ground() 
    i_out_sensor.no_fault() 
    i_out_sensor.short_to_ground() 

첫 번째 방법은 당신이 순서에 직접 액세스 할 수있는 장점이있다 Channel 개체입니다.당신이 채널에 동일한 작업을 적용하고 있기 때문에, 당신은 더 간단한 인터페이스 모두를 반복 할 수 있습니다

def main(): 
    fault_board = FaultInsertionBoard('COM3') 
    for channel in fault_board.channels: 
     channel.no_fault() 
     channel.short_to_ground() 

편리한 방법

당신의 작업을 x.no_fault(); x.short_to_ground() 여러 번 사용하는 것이 나타납니다 당신의 코드. 이 경우 편의 메소드라고 불리는 것을 만드는 것이 도움이됩니다. 당신은 추가 할 수있는 다음 Channel에 :

def reset(self): 
    self.no_fault() 
    self.short_to_ground() 

그리고 main 다음과 같이 수 : 당신은 FaultInsertionBoard``의 코드를 표시하지 않습니다

def main(): 
    fault_board = FaultInsertionBoard('COM3') 
    for channel in fault_board.channels: 
     channel.reset()