• 0
Tore Sæderup

Getting started with the PMON1

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];

}

 

 

Share this post


Link to post
Share on other sites

4 answers to this question

Recommended Posts

  • 0

Hi @Tore Sæderup,

I don't have any immediate advice at the moment, but I am taking a look into the datasheets for the Pmod Pmon1 to see if I can create some code for it since we don't have anything for it at this point in time either.

Thanks,
JColvin

Share this post


Link to post
Share on other sites
  • 0

Hi @Tore Sæderup,

We have not forgotten about your thread. The forums have being very busy the last few weeks and have not had time to work on this. This is still on our things to do list. Very sorry about the inconvenience this might be causing.

thank you for your patience,

Jon

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now