<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def read_adc(self, cabinet, frame, board):
 """Read ADC data from the BMP including voltages and temperature. Returns ------- :py:class:`.ADCInfo` """

        response = self._send_scp(cabinet, frame, board, SCPCommands.bmp_info,
                                  arg1=BMPInfoType.adc, expected_args=0)
        data = struct.unpack("<"   # Little-endian
                             "8H"  # uint16_t adc[8]
                             "4h"  # int16_t t_int[4]
                             "4h"  # int16_t t_ext[4]
                             "4h"  # int16_t fan[4]
                             "I"   # uint32_t warning
                             "I",  # uint32_t shutdown
                             response.data)

        return ADCInfo(
            voltage_1_2c=data[1] * BMP_V_SCALE_2_5,
            voltage_1_2b=data[2] * BMP_V_SCALE_2_5,
            voltage_1_2a=data[3] * BMP_V_SCALE_2_5,
            voltage_1_8=data[4] * BMP_V_SCALE_2_5,
            voltage_3_3=data[6] * BMP_V_SCALE_3_3,
            voltage_supply=data[7] * BMP_V_SCALE_12,
            temp_top=float(data[8]) * BMP_TEMP_SCALE,
            temp_btm=float(data[9]) * BMP_TEMP_SCALE,
            temp_ext_0=((float(data[12]) * BMP_TEMP_SCALE)
                        if data[12] != BMP_MISSING_TEMP else None),
            temp_ext_1=((float(data[13]) * BMP_TEMP_SCALE)
                        if data[13] != BMP_MISSING_TEMP else None),
            fan_0=float(data[16]) if data[16] != BMP_MISSING_FAN else None,
            fan_1=float(data[17]) if data[17] != BMP_MISSING_FAN else None,
        )