REXYGEN Community Forum
    • Categories
    • Recent
    • Tags
    • Popular
    • Login

    Problems Sequential reading channels ADC MCP3424 via I2C

    Communication (RS232, RS485, I2C, SPI, UDP, TCP, ...)
    2
    3
    37
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • A
      AlexanderH
      last edited by

      Hello, I am Alexander and probing a lot with Rexygen, with good results until now. However, at this moment I am trying to read data with the Rexlang block (I2C communication) from an ADC (analog-digital converter) MCP3424, without succes. I am relatively new with respect to the Rexlang block and i2c. I know that I have to send a not-acknowledge (NAK) bit and a stop bit to exit the current read operation and send a new read command for the latest conversion data. However I don't know how to do that.

      Hopefully somebody is willing to help me with my problem.
      Many thanks in advance.

      Below my code:

      /************************************************************
      *
      * REXLANG - Reading data from MCP3424 AD converter via I2C
      *
      *************************************************************/
      
      string parameter(0) i2c_dev; // the I2C bus is defined by the p0 parameter
      
      //assigning variables to outputs, these variables are WRITE-ONLY
      long output(0) channel1; // output of value of ADC channel 1
      long output(1) channel2; // output of value of ADC channel 2
      long output(2) channel3; // output of value of ADC channel 3
      long output(3) channel4; // output of value of ADC channel 4
      
      //declaration of variables
      long i2c_bufTx[3]; //buffer for transmitting data
      long i2c_bufRx[3]; //buffer for receiving data
      long i2c_bus_handle;
      long i2c_chip_address;
      long i2c_write_count;
      long i2c_read_count;
      long i2c_ret_fun;
      
      //the init procedure is executed once when the REXLANG function block initializes
      int init(void)
      {
        i2c_bus_handle = OpenI2C(i2c_dev); // open I2C bus
        /* Address: 1 1 0 1 A2 A1 A0 */
        i2c_chip_address = 0x68; // 7-bit address of the I2C device
        
        return 0;
      }
      
      //the main procedure is executed once in each sampling period
      long main(void)
      {
        /* Configuration register: 
           =====================================================================================
           | bit 7                | bit 6-5        | bit 4          | bit 3-2     | bit 1-0      |
           -------------------------------------------------------------------------------------
           | 1 = start conversion | 00 = channel 1 | 1 = continuous | 00 = 12-bit | 00 = gain x1 |
           | 0 = no effect        | 01 = channel 2 | 0 = one-shot   | 01 = 14-bit | 01 = gain x2 |
           |                      | 10 = channel 3 |                | 10 = 16-bit | 10 = gain x4 |
           |                      | 11 = channel 4 |                | 11 = 18-bit | 11 = gain 8x |
           =====================================================================================
        */
        i2c_bufTx[0] = 0x90; // read channel 1, continuous, 12bit, gain 1 (see MCP3424 datasheet)
        i2c_write_count = 1;
        i2c_read_count = 2;
        //Sending data via I2C
        i2c_ret_fun = I2C(i2c_bus_handle, i2c_chip_address, i2c_bufTx, i2c_write_count, i2c_bufRx, i2c_read_count);
        channel1 = ((i2c_bufRx[0]<<8) + i2c_bufRx[1])/2;
        
        return  0;
      
        i2c_bufTx[0] = 0xB0; // read channel 2 continuous, 12bit, gain 1 (see MCP3424 datasheet)
        i2c_write_count = 1;
        i2c_read_count = 2;
        //Sending data via I2C
        i2c_ret_fun = I2C(i2c_bus_handle, i2c_chip_address, i2c_bufTx, i2c_write_count, i2c_bufRx, i2c_read_count);
        channel2 = ((i2c_bufRx[0]<<8) + i2c_bufRx[1])/2;
        
        return 0;
      }
      
      //the exit procedure is executed once when the task is correctly terminated
      // (system shutdown, downloading new control algorithm, etc.)
      long exit(void)
      {
        if(i2c_bus_handle>=0) Close(i2c_bus_handle); // close I2C bus
        return 0;
      }
      1 Reply Last reply Reply Quote 0
      • J
        Jan Reitinger
        last edited by

        @AlexanderH Hi Alexander,

        Great to see you experimenting with REXYGEN and getting good results so far! It’s nice that you started from the example library — that’s definitely the right approach. The I2C function in REXYGEN works a bit differently compared to Arduino or other low-level implementations. Since REXYGEN tasks usually don’t run with very short cycle times, a single I2C call performs both write and read operations within one cycle. This command takes care of sending the message, waiting briefly, and then reading the response. That means you don’t need to manually handle the NAK or stop condition — the function itself takes care of it.

        I looked through your code and have a few notes that might help:

        • I noticed that right after calculating channel1, you have a return 0;. Because of that, the code for channel2 never runs — I guess that’s just for debugging, but it’s worth pointing out.
        • In each REXYGEN cycle, you currently configure the converter for continuous read mode. This might not behave as you expect, and it’s probably unnecessary. Try switching to one-shot mode first and see what kind of values you get. Later, you can set continuous mode once, and then in your main() you can just read the data by setting i2c_write_count = 0. That way, the I2C function won’t send any configuration bytes, it will only read — according to the documentation, that should work.
        • You can use the Trace() function to print out the value of i2c_ret_fun for debugging. Keep in mind that you need to enable these messages in the system log:
          Go to Target → Diagnostic messages, tick Information in Function block messages, and make sure Enable logging is checked in the Options tab of the block properties dialog. Only then you’ll see the messages in the System log.
        • And finally, double-check the I2C address of the MCP3424 — it’s configurable, so make sure it matches your hardware setup.

        Hope this helps you move forward! Please let us know how it goes — it’s always interesting to see REXLANG + I2C projects in action.

        Cheers,
        Jan

        A 1 Reply Last reply Reply Quote 0
        • A
          AlexanderH @Jan Reitinger
          last edited by

          @Jan-Reitinger Dear Jan, Thanks for these valuable tips :-). I will start with it this weekend. Hopefully I will succeed. If not, I will let you know via this forum. I will keep you posted. Greetings, Alex

          1 Reply Last reply Reply Quote 0
          • First post
            Last post

          This is a community forum for REXYGEN users and fans. Detailed information can be found at REXYGEN homepage.

          There is also an outdated REXYGEN community forum.

          Powered by NodeBB.