LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Labwindows CVI I2C 8574 with Labjack

Solved!
Go to solution

Hello forum,

 

I start again, after a long break of about 10 years to program with CVI...

 

Here my problem.... I try to communicate with a 8574 portexpander (later maybe 23017) via I2C with a USB connected Labjack-module (Labjack U6).

 

The Code on the Labjack-site is not so helpful......

 

So I would be very pleased If someone had a few routines for me....

 

Thank You in advance

0 Kudos
Message 1 of 8
(3,864 Views)

If you are not proficient with I2C, consider using SPI instead.  SPI is simpler than I2C, and perhaps best of all you can use a loopback for initial testing.  Many have had success with the Microchip MCP23S17.

 

We call the U6 a UD device because it works with the UD library on Windows.

 

Here is our documentation for I2C on the U6 through the UD library:

 

https://labjack.com/support/datasheets/u6/high-level-driver/example-pseudocode/i2c

 

We have a CVI example for the UD library here:

 

https://labjack.com/support/software/examples/ud/labwindowscvi

 

Just that one CVI example, but the idea is that it is showing you what is unique about CVI.  Beyond that you can adapt any of our C/C++ code to CVI:

 

https://labjack.com/support/software/examples/ud/vc6

 

There is an I2C example in the "Any Device" folder.

 

Also check out our Serial Protocols app notes:

 

https://labjack.com/support/app-notes/Serial-Protocols

 

0 Kudos
Message 2 of 8
(3,814 Views)

Many thanks first!

Unfortunately, I2C is a requirement .... I'll look at the tips, thank you!

0 Kudos
Message 3 of 8
(3,793 Views)

 

Something is moving on the SDA line, I am trying to output values to the 8574A (address 0x38 .... therefore 0x70), this can be seen in the oscilloscope, but the outputs of the IC do not move. I just attach the snippet of code I'm using .... written down quickly, so please don't complain 😉 Address for the 8574 is 0x38, so after Shift 1 then 0x70. do I see that correctly that the value is then passed "decimal"?
 
-----------------------------------------------------------------
 
 

The snipped is based on the "simpleCVI" example from the LJ-site

 

I have a warning in line 170

 

AddRequest(lngHandle, LJ_ioI2C_COMMUNICATION, LJ_chI2C_WRITE, numWrite, array, 0);

 

170, 77 warning: incompatible pointer to integer conversion passing 'long [20]' to parameter of type 'long'

 

 

 

 

#define ON 1
#define OFF 0

#include <userint.h>
#include <utility.h>
#include <stdio.h>

#include "c:\p//---------------------------------------------------------------------------
//
// simplecvi.c
//
//----------------------------------------------------------------------
//

rogram files\LabJack\Drivers\LabJackUD.h"

int adr_8574 = 70;

long lngErrorcode;
long lngIOType = 0;
long lngChannel = 0;
double dblValue = 0;
double Value2 = 0;
double Value3 = 0;
double ValueDIBit = 0;
double ValueDIPort = 0;
double ValueDOBit = 0;
LJ_HANDLE lngHandle = 0;
char err[255];
long array[20];
int ch;
int counter = 0;
int max_number = 500;
int eventData2 = 0;
int numWrite = 0;

int dummy = 0;
void set_port(double port, double status);
void config_labjack(void);

void error_message(long code);
void execute(void);
void job_1(void);


main()
{
config_labjack();

while (counter++ < max_number)
{
job_1();


while (KeyHit())
{
ch=GetKey();
printf("\n\nTaste = %c\n\n ", ch);
if (ch=='e')
{
counter = max_number;
set_port(16,OFF);
set_port(17,OFF);
}
}
}
return 0;
}
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
void job_1(void)
{
printf("counter = %d\n",counter); // Abwechselndes Ein- und Ausschalten zweier LED, Ausgabe
Delay(0.25); // des Counters, Abfrage auf Taste "e" für vorzeitiges
set_port(16,ON); // Beenden
set_port(17,OFF);

Delay(0.25);
set_port(16,OFF);
set_port(17,ON);

numWrite = 1;

AddRequestPtr(lngHandle, LJ_ioI2C_COMMUNICATION, LJ_chI2C_WRITE, numWrite, array, 0);
array[0]++;
if (array[0]>255)
{
array[0] = 0;
}

printf("\n\narray[0] = %d\n\n ", array[0]);
}

//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
void execute(void)
{
lngErrorcode = GoOne (lngHandle);
if(lngErrorcode) error_message(lngErrorcode);
}
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------

void set_port(double port, double status)
{

lngErrorcode = AddRequest (lngHandle, LJ_ioDIGITAL_BIT_OUT, port, status, 0, 0);
if(lngErrorcode) error_message(lngErrorcode);

execute();
}

//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------

void config_labjack(void)
{

lngErrorcode = OpenLabJack (LJ_dtU6, LJ_ctUSB, "1", 1, &lngHandle); // LJ_dtU6 --- welches Gerät
// LJ_ctUSB --- conection via USB
// "1" Adresse als String!!!
// 1 --- ignore adress, use next available one
// lngHandle --- Rückgabe des handles (reference)
if(lngErrorcode) error_message(lngErrorcode); // Fehlermeldung auf Konsole, wenn z. B. LJ nicht da

//--------------------------------------------------------------------------------------------------------------------------------------------
// Gerät konfigurieren
//--------------------------------------------------------------------------------------------------------------------------------------------

// LJ_ioGET_DIGITAL_BIT --- sets direction to input.
// LJ_ioGET_DIGITAL_BIT_DIR
// LJ_ioGET_DIGITAL_BIT_STATE
// LJ_ioGET_DIGITAL_PORT --- sets directions to input.x1 is number of bits.
// LJ_ioGET_DIGITAL_PORT_DIR --- x1 is number of bits.
// LJ_ioGET_DIGITAL_PORT_STATE --- x1 is number of bits.
// LJ_ioPUT_DIGITAL_BIT --- sets direction to output.
// LJ_ioPUT_DIGITAL_PORT --- sets directions to output.x1 is number of bits.

// Bit numbers
// FI00 - FI07 --- 0..7
// EI00 - EI07 --- 8..15
// CI00 - CI03 --- 16..19
// MI00 - MI02 --- 20..22
//
//

// Konfiguration
//==============
// Aus-und Eingänge definieren
lngErrorcode = AddRequest (lngHandle, LJ_ioPUT_DIGITAL_BIT, 16, 1, 0, 0); // CI00 als active high-Ausgang
if(lngErrorcode) error_message(lngErrorcode);
lngErrorcode = AddRequest (lngHandle, LJ_ioPUT_DIGITAL_BIT, 17, 1, 0, 0); // CI01 als active high-Ausgang
if(lngErrorcode) error_message(lngErrorcode);

execute();

//-----------------------------------------------------------------------

// I2C für den 8574 vorbereiten

//Assign the (hardware)adress to a handle
AddRequest(lngHandle, LJ_ioPUT_CONFIG, LJ_chI2C_ADDRESS_BYTE, adr_8574, 0, 0);
array[0] = 0;
numWrite = 1;
//The following code configures I2C to enable the "no stop when restarting" I2C feature
AddRequest(lngHandle, LJ_ioPUT_CONFIG, LJ_chI2C_OPTIONS, 4,0,0);
AddRequest(lngHandle, LJ_ioPUT_CONFIG, LJ_chI2C_SPEED_ADJUST, 0, 0, 0);
AddRequest(lngHandle, LJ_ioI2C_COMMUNICATION, LJ_chI2C_WRITE, numWrite, array, 0);
execute();

//--------------------------------------------------------

}

 

//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
void error_message(long code)
{
ErrorToString(code,err);
printf("\nError message = %s\n",err);
}
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------

 

0 Kudos
Message 4 of 8
(3,786 Views)
Solution
Accepted by topic author MarHilMen

The address of your I2C sensor should be passed as an integer. 0x70 is 112 as a decimal value, so you should set adr_8574 to be 112.

 

AddRequest is not 64-bit address safe but AddRequestPtr is 64-bit safe and should be used anytime you need to pass an array. Instead of using AddRequest for LJ_chI2C_WRITE (or LJ_chI2C_READ) please use AddRequestPtr and that should fix the warning you are seeing. See the AddRequest documentation here:

 

https://labjack.com/support/datasheets/u6/high-level-driver/function-reference/addrequest

 

It does not appear that you are setting your SDA or SCL pin numbers, please be sure to add code to do this. See the pseudocode for configuration on our I2C page or our C++ example:

 

https://labjack.com/support/app-notes/i2c

 

Those are the only few things that jumped out as potential issues. If you modify your code based on our suggestions above and are still having issues please send over a capture of your data line and let us know what you changed in your code. We can continue to assist from there.

0 Kudos
Message 5 of 8
(3,766 Views)

Thank you very much, that was very helpful !!!!


I forgot the address assignment (line 106) or I didn't understand it correctly.

I will send the little program along, maybe someone will help it .....

0 Kudos
Message 6 of 8
(3,729 Views)

We can help a bit more if you are still having issues. It looks like you have all of the configuration you need to get I2C setup with your U6 but there may be some additional things to consider for your specific sensor. Is this the sensor you are using?

 

https://www.ti.com/product/PCF8574A

0 Kudos
Message 7 of 8
(3,714 Views)

Yes, indeed it is the 8574 ... and it now works on the LabJack U6. Next I want to try the 23017 and then use it to plan the corresponding boards. I still have a USB to I2C adapter with an FT232H from FTDI, but since I haven't been able to output anything on the USB port via CVI so far, that's a bit problematic ....

0 Kudos
Message 8 of 8
(3,697 Views)