Jump to content
  • 0

Getting started with the PMON1


Tore Sæderup

Question

Greetings

I am a lowly programming intern at a company manufacturing (among other things) small computers for embedded integration. I have been handed a handful of Digilent PMOD devices that looked interesting for the company to write drivers for. So far, it has been a valuable (and quite fun) experience, but I've hit a wall with the Pmod PMON1. My experience is in mechanics and pure programming and my electrical knowledge is limited. An electrical engineer helped me set up a monitored device with controlable load, and I know Digilent's approach to the I²C protocol from the Pmod HYGRO. Now, following the same protocol and what I understand from the documentation, I have written the code below. I would assume to get two different values from the digilent_pmodpmon1_get_resistance() calls to reflect the changed load, but I just get the same data twice: 32, 10.

What am I misunderstanding?

Spoiler

 

int main ( int argc, char *argv[] )
{
    i2c_setup();   // same method I used for the HYGRO, so this should work

    set_i2c_register(i2cAddress, noOp);  // Awaken the device

    digilent_pmodpmon1_zero_wiper();  // I assume that I now am zeroing the internal potentiometer so I have a reference point

    digilent_pmodpmon1_get_resistance();  // I assume that I am here getting the value of the internal potentiometer (might be zero or whatever the monitored device has changed it to)

    printf("change current now\n" );

    sleep(2);  // At this point, I manually change the load of the monitored device while the program sleeps

    digilent_pmodpmon1_get_resistance();  // Again, I assume that I am getting the value of the potentiometer. This should now be different since the load has changed

    i2cClose();

    return 1;
}

/* --- CONSTANTS --- */  // Addresses taken from the Analog documentation
/** @brief Address of the I2C device. */
const int i2cAddress = 0x2F;  // I assume that this is the main address, since it only appeared on my i2cdetect after plugging in the monitored device

const int i2cReadAddress = 0x30;  // the address after the assumed main address. Also appeared after plugging in the monitored device, so I assume that one of the two will contain the readback data

/** @brief No operation */
const int noOp = 0x0;

/** @brief  register for zeroing the wiper */
const int zeroWiperReg = 0x02;

/** @brief Read contents of RDAC register */
const int readRdac = 0x05;

/** *@brief The board has 2 I2C ports: i2c-0 is PMOD A, i2c-1 is PMOD B. */
const char deviceLocation[11] = "/dev/i2c-0";

/* --- VARIABLES --- */

/** @brief I2C device handle. */
static int i2cFileDescriptor;

/* --- METHODS --- */

/** @brief Opens the Linux device.
* @details Wakes the device by writing a 0 to it.
* @return i2cFileDescriptor on success, exits program on failure. */
int i2c_setup()
{
    i2cFileDescriptor = open(deviceLocation, O_RDWR);
    usleep(20000); // Give the sensors time to wake up
    if ( i2cFileDescriptor < 0)
    {
        exit(1);
    }
    if (ioctl( i2cFileDescriptor, I2C_SLAVE_FORCE, i2cAddress) < 0)
    {
        printf("Failed to acquire bus access and/or talk to slave.\n");
        //ERROR HANDLING; you can check errno to see what went wrong
    }
    usleep(20000);

    return  i2cFileDescriptor;
}

/** @brief Sets the value of a register on the Pmod PMON1 device.
* @details Used for the setup methods.
* @return 1 on error, 0 on success.
* @param reg The register thas will be written to.
* @param value The value to write. */
int set_i2c_register(unsigned char reg, unsigned char value)
{
    unsigned char outbuf[2];
    struct i2c_rdwr_ioctl_data packets;
    struct i2c_msg messages[1];

    messages[0].addr  = i2cAddress;
    messages[0].flags = 0;
    messages[0].len   = sizeof(outbuf);
    messages[0].buf   = outbuf;

    // The first byte indicates which register we'll write to.
    outbuf[0] = reg;

    // The second byte indicates the value to write.
    outbuf[1] = value;

    // Transfer the i2c packets to the kernel and verify it worked.
    packets.msgs  = messages;
    packets.nmsgs = 1;
    if(ioctl( i2cFileDescriptor, I2C_RDWR, &packets) < 0) {
        perror("Set: Unable to send data");
        return 1;
    }
    return 0;
}

/** @brief Closes the Linux device.
* @return Void. */
void i2cClose()
{
    close( i2cFileDescriptor);
}


/** @brief Write the RDAC Register and Place the Wiper at Zero Scale
* @details
* @return */
void digilent_pmodpmon1_zero_wiper()
{

    int length;
    unsigned char buffer[2];
    //----- WRITE BYTES -----
    buffer[0] = zeroWiperReg;
    length = 1;            // Number of bytes to write
    if (write(i2cFileDescriptor, buffer, length) != length)        //write() returns the number of bytes actually written, if it doesn't match then an error occurred (e.g. no response from the device)
    {
        /* ERROR HANDLING: i2c transaction failed */
        printf("Failed to write to the i2c bus.\n");
        exit(1);
    }
    usleep(20000);    //give the device time to answer.
}

/** @brief Gets the resistance on the connected device.
* @details Reading from the device requires first writing dummy data to the relevant register, then waiting, and then reading from the same register.
* @return
*/
int digilent_pmodpmon1_get_resistance()
{

    int length;
    unsigned char buffer[2];
    //----- WRITE BYTES -----
    buffer[0] = readRdac;
    length = 1;            // Number of bytes to write
    if (write(i2cFileDescriptor, buffer, length) != length)        //write() returns the number of bytes actually written, if it doesn't match then an error occurred (e.g. no response from the device)
    {
        // ERROR HANDLING: i2c transaction failed
        printf("Failed to write to the i2c bus.\n");
        exit(1);
    }
    usleep(20000);    //give the device time to answer.
    //----- READ BYTES -----
    length = 2;            // Number of bytes to read
    if (read(i2cFileDescriptor, buffer, length) != length)        //read() returns the number of bytes actually read, if it doesn't match then an error occurred (e.g. no response from the device)
    {
        //ERROR HANDLING: i2c transaction failed
        printf("Failed to read from the i2c bus.\n");
        exit(1);
    }
    printf("%i, %i\n", buffer[0], buffer[1]);

    return buffer[0];

}

 

 

Link to comment
Share on other sites

4 answers to this question

Recommended Posts

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...