import spidev
import time

class MCP3208:
    def __init__(self, bus=0, device=0):
        # Initialize SPI bus and device
        self.spi = spidev.SpiDev()
        self.spi.open(bus, device)  # Default SPI bus 0, device 0 (you can change as needed)
        self.spi.max_speed_hz = 1000000  # Adjust based on your needs (e.g., 1MHz)
        self.spi.mode = 0b00  # Set SPI mode (Mode 0 for MCP3208)
    
    def read(self, channel):
        """
        Read the ADC value from the specified channel (0-7).
        """
        if channel < 0 or channel > 7:
            raise ValueError("Channel must be between 0 and 7.")

        # MCP3208 sends a 3-byte response, which needs to be processed
        # Start with the single bit control byte, followed by the channel selection
        # MCP3208 uses 3 bits for the channel: 0-7
        # The command byte looks like this:
        # |  Start | Single-ended | Channel (3 bits) | Don't Care (1 bit) |
        
        # Construct the 3-byte command
        # Start bit (1) | Single-ended (1) | Channel (3 bits) | Don't care (1) | End (1)
        command = [1, (8 + channel) << 4, 0]

        # Send command and receive the 3-byte result
        result = self.spi.xfer2(command)

        # Combine the result bytes (result is a list of 3 bytes)
        # First byte is ignored, we want the 2nd and 3rd bytes for our result
        value = ((result[1] & 0x03) << 8) | result[2]  # Convert to 10-bit value (0-1023)

        return value
    
    def close(self):
        """Close SPI connection."""
        self.spi.close()

# Example usage:
if __name__ == "__main__":
    adc = MCP3208()
    try:
        while True:
            for i in range(8):
                adc_value = adc.read(i)
                print(f'ADC[{i}]: {adc_value}')
            time.sleep(0.5)
    finally:
        adc.close()