• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1"""Base class for Blueberry controllers using Arduino board.
2
3This module uses pyserial library to communicate with Arduino UNO board.
4
5About Arduino code, please refer to the code of following Arduino project:
6Internal link
7"""
8
9import time
10from typing import Dict
11from mobly.signals import ControllerError
12import serial
13
14
15class ArduinoBase(object):
16  """Implements an Arduino base class.
17
18  Attributes:
19    config: A device configuration.
20    serial: serial object, a serial object which is used to communicate with
21      Arduino board.
22  """
23
24  def __init__(self, config: Dict[str, str]):
25    """Initializes an Arduino base class."""
26    self._verify_config(config)
27    self.config = config
28    self.serial = serial.Serial(config['arduino_port'], 9600)
29    self.serial.timeout = 30
30    # Buffer between calling serial.Serial() and serial.Serial.write().
31    time.sleep(2)
32
33  def _verify_config(self, config):
34    """Checks the device config's required config parameters.
35
36    Args:
37      config: dict, Mobly controller config for ArduinoBass. The config should
38        include the key "arduino_port" whose value is a string representing
39        Arduino board name. e.g. /dev/ttyACM0.
40    """
41    if 'arduino_port' not in config:
42      raise ControllerError('Please provide an Arduino board port for the'
43                            ' ArduinoBase in Mobile Harness config')
44
45  def _send_string_to_arduino(self, tx_string):
46    """Sends a particular string to communicate with Arduino.
47
48    The method requires that Arduino code can read string which is received from
49    a python serial object and then send the same string to the serial object.
50
51    An example of Arduino code:
52      String kRxString = "";
53      void setup() {
54        ...
55      }
56      void loop() {
57        if (Serial.available() > 0) {
58          kRxString = Serial.readString();
59          ...
60          Serial.write(kRxString.c_str());
61        }
62      }
63
64    Args:
65      tx_string: string, is used to be sent to Arduino port for making the
66        controlled device perform action. After Arduino receives the string, it
67        will send a response which is the same string.
68
69    Returns:
70      The time it takes for waiting a response, in seconds.
71
72    Raises:
73      ControllerError: raised if not received a response from Arduino.
74    """
75    self.serial.write(str.encode(tx_string))
76    start_time = time.time()
77    rx_string = self.serial.read_until(tx_string, len(tx_string)).decode()
78    if rx_string == tx_string:
79      return time.time() - start_time
80    raise ControllerError('Timed out after %ds waiting for the string "%s" from'
81                          ' Arduino.' % (self.serial.timeout, tx_string))
82