Пример #1
0
    def read(self, channels, samples_per_channel, timeout=10.0):
        '''
        Args:
            channels:            int/list, [1, 2], the desired channel(s).
            samples_per_channel: int. number of points read.
            timeout:             float, (>=0), default 10.0, unit Second, execute timeout.

        Exception:
            InvalidHardwareChannel() if provided channel is not 1 or 2
            InvalidSampleCount() if samples_per_channel is of bad value
            InvalidTimeout() if invalid timeout value

        Returns:
            list, unit mv, ADC measurement data.
        '''
        if isinstance(channels, int) and channels not in [1, 2]:
            raise InvalidHardwareChannel("channel is not 1 or 2")
        if isinstance(channels, list) and (0 == len(channels)
                                           or len(channels) > 2):
            raise InvalidHardwareChannel("channel is not 1 or 2")
        if isinstance(
                channels,
                list) and 1 == len(channels) and channels[0] not in [1, 2]:
            raise InvalidHardwareChannel("channel is not 1 or 2")
        if isinstance(
                channels,
                list) and 2 == len(channels) and channels[0] not in [1, 2]:
            raise InvalidHardwareChannel("channel is not 1 or 2")
        if isinstance(
                channels,
                list) and 2 == len(channels) and channels[1] not in [1, 2]:
            raise InvalidHardwareChannel("channel is not 1 or 2")
        if samples_per_channel < Audio005002Def.MINI_NUM:
            raise InvalidSampleCount("samples_per_channel is of bad value")
        if timeout < 0 or timeout > 10.0:
            raise InvalidTimeout("invalid timeout value")

        data_info = []
        start_time = time.time()
        while True:
            try:
                if isinstance(channels, list):
                    for i in range(len(channels)):
                        data = self._read_voltage_points(
                            channels[i], samples_per_channel,
                            int(timeout * 1000))
                        if len(channels) == 2:
                            data_info.append(data)
                        else:
                            data_info = data
                else:
                    data_info = self._read_voltage_points(
                        channels, samples_per_channel, int(timeout * 1000))
                return data_info
            except Exception as e:
                if time.time() - start_time > timeout:
                    raise InvalidTimeout("Timeout")
                if e.__class__.__name__ == 'Audio005002Exception':
                    raise Audio005002Exception("{}".format(str(e)))
Пример #2
0
    def read_buffer_statistics(self, session_id, samples_per_channel=1, timeout=10.0):
        '''
        This function takes a number of samples to calculate RMS/average/max/min value of the set of sampled value.

        Values read are in mV or mA, which is determined by DRI.

        This function can only be called in continuous mode, a.k.a, after configure_input_channel(),
            start_buffered_acquisition() function is called. Return 0 for the channels that are not enabled.
        The returned value is calibrated if calibration mode is `cal`. The data read back from the voltage channel
            is calibrated in mV. The data read back in the current channel is calibrated in uA when max_range is 1,
            and it is calibrated in mA when max_range is 1000.
        During continuous sampling, the functions, like configure_input_channel() read(), cannot be called.

        Args:
            session_id: int, [1, 2], 1 mean the channel for 'voltage', 2 mean the channel for 'current'.
            samples_per_channel: int, [1~512], defualt 1, samples count taken for calculation.
            timeout: float, (>=0), default 10.0, the maximum duration the acquisition can take,
                                   in seconds, before returning an exception.

        Exception:
            InvalidHardwareChannel() if provided session_id is not 1 or 2.
            InvalidSampleCount() if provided samples_per_channel is not an integer or is <1 or >512.
            InvalidTimeout() if provided timeout is <0.

        Returns:
            dict, the channel data to be measured. {
                (rms, unit),
                (avg, unit),
                (max, unit),
                (min, unit)
            },
            for voltage channel #1 current channel #2.

        Examples:
            odin.configure_input_channel(1, 'battery', 1000)
            odin.start_buffered_acquisition(1)
            result = odin.read_buffer_statistics(1, 10)
            print(result)
            odin.stop_buffered_acquisition(1)
        '''
        if session_id not in [1, 2]:
            raise InvalidHardwareChannel("Invalid channel")

        if not isinstance(samples_per_channel, int) or samples_per_channel < 1 or samples_per_channel > 512:
            raise InvalidSampleCount("Invalid sample count")

        if timeout < 0:
            raise InvalidTimeout("Invalid timeout")

        if not self.continuous_sample_mode:
            return 0

        if not self.active_channel:
            return 0
        channel = self.active_channel
        channel_data = list()
        result = dict()
        ch_input_config_dict = {1: self.ch1_input_config, 2: self.ch2_input_config}
        ch_input_config = ch_input_config_dict[channel]
        pin_id, adc_channel = (OdinDef.READ_CURR_BIT, OdinDef.CHANNEL_1) if ch_input_config['channel'] == 'current' \
            else (OdinDef.READ_VOLT_BIT, OdinDef.CHANNEL_0)
        pin_level = OdinDef.HIGH_LEVEL if ch_input_config['type'] == 'battery' else OdinDef.LOW_LEVEL
        self.tca9538.set_pin(pin_id, pin_level)

        if channel == 1:
            cal_type = OdinDef.BATT_VOLT_READ if ch_input_config['type'] == 'battery' else OdinDef.CHARGE_VOLT_READ
        else:
            if ch_input_config['type'] == 'battery':
                if ch_input_config['max_range'] == 1:
                    cal_type = OdinDef.BATT_CURR_READ_1mA
                elif ch_input_config['max_range'] == 1000:
                    cal_type = OdinDef.BATT_CURR_READ_1A
            else:
                cal_type = OdinDef.CHARGE_CURR_READ

        try:
            channel_data = self.ad7175.get_continuous_sampling_voltage(adc_channel, samples_per_channel)
        except Exception as e:
            self.stop_buffered_acquisition(session_id)
            if (OdinDef.ADC_ERROR_BIT & self.ad7175.read_register(OdinDef.STATUS_REG_ADDR)):
                reg_data = self.ad7175.read_register(OdinDef.DATA_REG_ADDR)

                if channel == 1:
                    if ch_input_config['type'] == 'battery':
                        volt_range = OdinDef.BATT_VOLT_RANGE
                    else:
                        volt_range = OdinDef.CHARGE_VOLT_RANGE

                    if reg_data == 0xFFFFFF:
                        raise OdinException('Overrange! the voltage value exceeds the {}V range'.format(volt_range))
                    elif reg_data == 0x000000:
                        raise OdinException('Underrange! the voltage value is lower than \
                                             negative {}V range'.format(volt_range))
                    else:
                        raise OdinException("{}".format(e.message))

                else:
                    if ch_input_config['type'] == 'battery':
                        if ch_input_config['max_range'] == 1:
                            curr_range = OdinDef.BATT_CURR_RANGE_1mA
                        else:
                            curr_range = OdinDef.BATT_CURR_RANGE_1A
                    else:
                        curr_range = OdinDef.CHARGE_CURR_RANGE

                    if reg_data == 0xFFFFFF:
                        raise OdinException('Overrange! the current value exceeds the {}A range'.format(curr_range))
                    elif reg_data == 0x000000:
                        raise OdinException('Underrange! the current value is lower than \
                                             negative {}A range'.format(curr_range))
                    else:
                        raise OdinException("{}".format(e.message))

            else:
                raise OdinException("{}".format(e.message))

        min_data = min(channel_data)
        max_data = max(channel_data)
        avg_data = sum(channel_data) / len(channel_data)
        rms_data = math.sqrt(sum([x**2 for x in channel_data]) / len(channel_data))

        if channel == 1:
            unit = OdinDef.UNIT_mV
            # battery channel: Vout = Vadc * 2.5, charge channel: Vout = Vadc * 4.0
            min_data, max_data, avg_data, rms_data = map(lambda volt: volt * 2.5
                                                         if ch_input_config['type'] == 'battery'
                                                         else volt * 4.0, [min_data, max_data, avg_data, rms_data])
            avg_data = self.calibrate(cal_type, avg_data)
            # set pin to default level.
            if ch_input_config['type'] == 'charge':
                self.tca9538.set_pin(OdinDef.READ_VOLT_BIT, OdinDef.HIGH_LEVEL)
        else:
            unit = OdinDef.UNIT_mA
            if ch_input_config['type'] == 'battery':
                min_data, max_data, avg_data, rms_data = map(lambda volt: volt,
                                                             [min_data, max_data, avg_data, rms_data])
            else:
                # charge channel: I = (Vadc - 24.7mV) / 2
                min_data, max_data, avg_data, rms_data = map(lambda volt: (volt - 24.7) / 2.0,
                                                             [min_data, max_data, avg_data, rms_data])

            avg_data = self.calibrate(cal_type, avg_data)

            if ch_input_config['max_range'] == 1:
                # uA convert to mA
                min_data, max_data, avg_data, rms_data = map(lambda volt: volt / 1000.0,
                                                             [min_data, max_data, avg_data, rms_data])
            # set pin to default level.
            if ch_input_config['type'] == 'charge':
                self.tca9538.set_pin(OdinDef.READ_CURR_BIT, OdinDef.HIGH_LEVEL)

        result['rms'] = (rms_data, unit + 'rms')
        result['avg'] = (avg_data, unit)
        result['max'] = (max_data, unit)
        result['min'] = (min_data, unit)

        return result
Пример #3
0
    def read(self, channels, samples_per_channel=1, timeout=10.0):
        '''
        Reads the specified number of samples from each channel.

        Values read are in mV or mA, which is determined by DRI.

        The returned value is calibrated if calibration mode is `cal`. The data read back from the voltage channel
            is calibrated in mV. The data read back in the current channel is calibrated in uA when max_range is 1,
            and it is calibrated in mA when max_range is 1000.

        Args:
            channels: int, [1, 2], 1 mean the channel for 'voltage', 2 mean the channel for 'current'.
            samples_per_channel: int, (>=1), default 1, the number of samples to read from each channel.
            timeout: float, (>=0), default 10.0, the maximum duration the acquisition can take,
                                   in seconds, before returning an exception.

        Exception:
            InvalidHardwareChannel() if provided channel is not 1 or 2.
            InvalidSampleCount() if provided samples_per_channel is not an integer or is <1.
            InvalidTimeout() if provided timeout is <0.

        Returns:
            list, [value1, ..., valueN], measured value defined by configure_input_channel()
                    voltage channel always in mV
                    current channel always in mA

        Examples:
            odin.configure_input_channel(2, 'battery', 1000, 1000)
            result = odin.read(2)
            print(result)
        '''
        if channels not in [1, 2]:
            raise InvalidHardwareChannel("Invalid channel")

        if not isinstance(samples_per_channel, int) or samples_per_channel < 1:
            raise InvalidSampleCount("Invalid sample count")

        if timeout < 0:
            raise InvalidTimeout("Invalid timeout")

        target_data = list()
        if channels == 1:
            if self.ch1_input_config['type'] == 'battery':
                cal_type = OdinDef.BATT_VOLT_READ
                self.tca9538.set_pin(OdinDef.READ_VOLT_BIT, OdinDef.HIGH_LEVEL)
            elif self.ch1_input_config['type'] == 'charge':
                cal_type = OdinDef.CHARGE_VOLT_READ
                self.tca9538.set_pin(OdinDef.READ_VOLT_BIT, OdinDef.LOW_LEVEL)

            for x in range(samples_per_channel):
                try:
                    volt_raw = self.ad7175.read_volt(OdinDef.CHANNEL_0)
                except Exception as e:
                    if (OdinDef.ADC_ERROR_BIT & self.ad7175.read_register(OdinDef.STATUS_REG_ADDR)):
                        reg_data = self.ad7175.read_register(OdinDef.DATA_REG_ADDR)

                        if self.ch1_input_config['type'] == 'battery':
                            volt_range = OdinDef.BATT_VOLT_RANGE
                        else:
                            volt_range = OdinDef.CHARGE_VOLT_RANGE

                        if reg_data == 0xFFFFFF:
                            raise OdinException('Overrange! the voltage value exceeds the {}V range'.format(volt_range))
                        elif reg_data == 0x000000:
                            raise OdinException('Underrange! the voltage value is lower than \
                                                 negative {}V range'.format(volt_range))
                        else:
                            raise OdinException("{}".format(e.message))
                    else:
                        raise OdinException("{}".format(e.message))
                # if channel is battery: Vout = Vadc * 2.5, if channel is charge: Vout = Vadc * 4
                volt = map(lambda x: (x * 2.5) if
                           self.ch1_input_config['type'] == 'battery' else (x * 4.0), [volt_raw])[0]
                volt = self.calibrate(cal_type, volt)

                target_data.append(volt)

            # set pin to default level.
            if self.ch1_input_config['type'] == 'charge':
                self.tca9538.set_pin(OdinDef.READ_VOLT_BIT, OdinDef.HIGH_LEVEL)

        else:
            if self.ch2_input_config['type'] == 'battery':
                if self.ch2_input_config['max_range'] == 1:
                    cal_type = OdinDef.BATT_CURR_READ_1mA
                elif self.ch2_input_config['max_range'] == 1000:
                    cal_type = OdinDef.BATT_CURR_READ_1A

                self.tca9538.set_pin(OdinDef.READ_CURR_BIT, OdinDef.HIGH_LEVEL)
            elif self.ch2_input_config['type'] == 'charge':
                cal_type = OdinDef.CHARGE_CURR_READ
                self.tca9538.set_pin(OdinDef.READ_CURR_BIT, OdinDef.LOW_LEVEL)

            for x in range(samples_per_channel):
                try:
                    volt = self.ad7175.read_volt(OdinDef.CHANNEL_1)
                except Exception as e:
                    if (OdinDef.ADC_ERROR_BIT & self.ad7175.read_register(OdinDef.STATUS_REG_ADDR)):
                        reg_data = self.ad7175.read_register(OdinDef.DATA_REG_ADDR)

                        if self.ch2_input_config['type'] == 'battery':
                            if self.ch2_input_config['max_range'] == 1:
                                curr_range = OdinDef.BATT_CURR_RANGE_1mA
                            else:
                                curr_range = OdinDef.BATT_CURR_RANGE_1A
                        else:
                            curr_range = OdinDef.CHARGE_CURR_RANGE

                        if reg_data == 0xFFFFFF:
                            raise OdinException('Overrange! the current value exceeds the {}A range'.format(curr_range))
                        elif reg_data == 0x000000:
                            raise OdinException('Underrange! the current value is lower than \
                                                 negative {}A range'.format(curr_range))
                        else:
                            raise OdinException("{}".format(e.message))
                    else:
                        raise OdinException("{}".format(e.message))
                # if channel is battery: I = Vadc, if channel is charge: I = (Vadc - 24.7mV) / 2
                current = (volt - 24.7) / 2.0 if self.ch2_input_config['type'] == 'charge' else volt
                current = self.calibrate(cal_type, current)
                if self.ch2_input_config['max_range'] == 1:
                    # uA convert to mA
                    current = current / 1000.0

                target_data.append(current)

            # set pin to default level.
            if self.ch2_input_config['type'] == 'charge':
                self.tca9538.set_pin(OdinDef.READ_CURR_BIT, OdinDef.HIGH_LEVEL)

        return target_data
Пример #4
0
    def read_buffer(self, session_id, samples_per_channel=1, timeout=10.0):
        '''
        This function takes a number of samples raw data of the set of sampled value.

        Values read are in mV, which is determined by DRI.

        This function can only be called in continuous mode, a.k.a, after configure_input_channel(),
            start_buffered_acquisition() function is called. Return 0 for the channels that are not enabled.
        During continuous sampling, the functions, like configure_input_channel() read(), cannot be called.

        Args:
            session_id: int, [1, 2], 1 mean the channel for 'voltage', 2 mean the channel for 'current'.
            samples_per_channel: int, [1~512], defualt 1, samples count taken for calculation.
            timeout: float, (>=0), default 10.0, the maximum duration the acquisition can take,
                                   in seconds, before returning an exception.

        Exception:
            InvalidHardwareChannel() if provided session_id is not 1 or 2.
            InvalidSampleCount() if provided samples_per_channel is not an integer or is <1 or >512.
            InvalidTimeout() if provided timeout is <0.

        Returns:
            list, [value,...] the unit of elements in the list is mV.

        Examples:
            odin.configure_input_channel(1, 'battery', 1000)
            odin.start_buffered_acquisition(1)
            result = odin.read_buffer(1, 10)
            print(result)
            odin.stop_buffered_acquisition(1)
        '''
        if session_id not in [1, 2]:
            raise InvalidHardwareChannel("Invalid channel")

        if not isinstance(samples_per_channel, int) or samples_per_channel < 1 or samples_per_channel > 512:
            raise InvalidSampleCount("Invalid sample count")

        if timeout < 0:
            raise InvalidTimeout("Invalid timeout")

        if not self.continuous_sample_mode:
            return 0

        if not self.active_channel:
            return 0

        raw_data = list()
        channel = self.active_channel
        ch_input_config_dict = {1: self.ch1_input_config, 2: self.ch2_input_config}
        ch_input_config = ch_input_config_dict[channel]
        pin_id, adc_channel = (OdinDef.READ_CURR_BIT, OdinDef.CHANNEL_1) if ch_input_config['channel'] == 'current' \
            else (OdinDef.READ_VOLT_BIT, OdinDef.CHANNEL_0)
        pin_level = OdinDef.HIGH_LEVEL if ch_input_config['type'] == 'battery' else OdinDef.LOW_LEVEL
        self.tca9538.set_pin(pin_id, pin_level)

        try:
            raw_data = self.ad7175.get_continuous_sampling_voltage(adc_channel, samples_per_channel)
        except Exception as e:
            self.stop_buffered_acquisition(session_id)
            if (OdinDef.ADC_ERROR_BIT & self.ad7175.read_register(OdinDef.STATUS_REG_ADDR)):
                reg_data = self.ad7175.read_register(OdinDef.DATA_REG_ADDR)

                if channel == 1:
                    if ch_input_config['type'] == 'battery':
                        volt_range = OdinDef.BATT_VOLT_RANGE
                    else:
                        volt_range = OdinDef.CHARGE_VOLT_RANGE

                    if reg_data == 0xFFFFFF:
                        raise OdinException('Overrange! the voltage value exceeds the {}V range'.format(volt_range))
                    elif reg_data == 0x000000:
                        raise OdinException('Underrange! the voltage value is lower than \
                                             negative {}V range'.format(volt_range))
                    else:
                        raise OdinException("{}".format(e.message))

                else:
                    if ch_input_config['type'] == 'battery':
                        if ch_input_config['max_range'] == 1:
                            curr_range = OdinDef.BATT_CURR_RANGE_1mA
                        else:
                            curr_range = OdinDef.BATT_CURR_RANGE_1A
                    else:
                        curr_range = OdinDef.CHARGE_CURR_RANGE

                    if reg_data == 0xFFFFFF:
                        raise OdinException('Overrange! the current value exceeds the {}A range'.format(curr_range))
                    elif reg_data == 0x000000:
                        raise OdinException('Underrange! the current value is lower than \
                                             negative {}A range'.format(curr_range))
                    else:
                        raise OdinException("{}".format(e.message))

            else:
                raise OdinException("{}".format(e.message))

        return raw_data
Пример #5
0
    def read_buffer(self, session_id, samples_per_channel=1, timeout=10.0):
        '''
        This function takes a number of samples raw data of the set of sampled value.

        Values read are in mV, which is determined by DRI.

        This function can only be called in continuous mode, a.k.a, after configure_input_channel(),
            start_buffered_acquisition() function is called. Return 0 for the channels that are not enabled.
        During continuous sampling, the functions, like configure_input_channel() read(), cannot be called.

        Args:
            session_id: int, [1, 2], 1 mean the channel for 'voltage', 2 mean the channel for 'current'.
            samples_per_channel: int, [1~512], defualt 1, samples count taken for calculation.
            timeout: float, (>=0), default 10.0, the maximum duration the acquisition can take,
                                   in seconds, before returning an exception.

        Exception:
            InvalidHardwareChannel() if provided session_id is not 1 or 2.
            InvalidSampleCount() if provided samples_per_channel is not an integer or is <1 or >512.
            InvalidTimeout() if provided timeout is <0.

        Returns:
            list, [value,...] the unit of elements in the list is mV.

        Examples:
            odin.configure_input_channel(1, 'battery', 1000)
            odin.start_buffered_acquisition(1)
            result = odin.read_buffer(1, 10)
            print(result)
            odin.stop_buffered_acquisition(1)
        '''
        if session_id not in [1, 2]:
            raise InvalidHardwareChannel("Invalid channel")

        if not isinstance(
                samples_per_channel,
                int) or samples_per_channel < 1 or samples_per_channel > 512:
            raise InvalidSampleCount("Invalid sample count")

        if timeout < 0:
            raise InvalidTimeout("Invalid timeout")

        if not self.continuous_sample_mode:
            return 0

        if not self.active_channel:
            return 0

        raw_data = list()
        channel = self.active_channel
        ch_input_config_dict = {
            1: self.ch1_input_config,
            2: self.ch2_input_config
        }
        ch_input_config = ch_input_config_dict[channel]
        if ch_input_config['channel'] == 'current':
            pin_id, adc_channel = (PSU001014Def.READ_CURR_BIT,
                                   PSU001014Def.CHANNEL_1)
        else:
            pin_id, adc_channel = (PSU001014Def.READ_VOLT_BIT,
                                   PSU001014Def.CHANNEL_0)
        pin_level = PSU001014Def.HIGH_LEVEL if ch_input_config[
            'type'] == 'battery' else PSU001014Def.LOW_LEVEL
        self.tca9538.set_pin(pin_id, pin_level)

        try:
            raw_data = self.ad7175.get_continuous_sampling_voltage(
                adc_channel, samples_per_channel)
        except Exception:
            raise

        return raw_data