The CY8CKIT-048 PSoC® board from the Analog Coprocessor Pioneer Kit is a pretty interesting board and easy to use with PSoC Creator Integrated Design Environment (IDE).
The package includes the Bridge Control Panel tool, that can be used to communicate with the board.
The tool allows us to receive/send data from/to our application using the I²C protocol. The data than can be plotted or can be saved to a file.
The "problem" with the tool is that it is Windows only, so we can't use it on devices running Linux, like the Raspberry Pi. That would allow us to create 24/7 monitoring applications for example.
But what if we could replace the Bridge Control Panel with something Linux/Raspberry Pi compatible?
First, lets take a look how the I²C communication over the USB connection works. There are two micro-controllers on the board:
- the main chip is a CY8C4A45LQI - this runs our application, that for example collects some sensor data and makes it available over a I²C interface
- the secondary chip is a CY8C586LTI implements the I2C-USB bridge - this can be used to access I²C data over an USB connection
The board exposes an USB HID interface with some proprietary protocol.
Fortunately, the protocol is pretty much the same as for the Cypress 3240 USB to I2C bridge, for which a library was already implemented by Kevin Kirkup:
https://github.com/kevinkirkup/cy3240-i2c-bridge
After migrating the project to libhidapi from obsolete the libhid, and inspecting with Wireshark the USB commands sent by the Bridge Control Panel:
I managed to update the implementation to get working with the CY8CKIT-048 PSoC® Analog Coprocessor Pioneer Kit.
The necessary changes were:
- adjusted the USB product and vendor IDs
- adjusted the protocol to work with the CY8CKIT-048 PSoC® Analog Coprocessor Pioneer Kit
- migrated the project from libhidapi from obsolete libhid
- made the code 64 bit compatible
The code is available in my GitHub account:
https://github.com/bluetiger9/cypress-usb-i2c-bridge.git dd
How to use it?To setup the board on a Raspberry Pi / Linux device and follow the bellow steps:
We need add some udev
rules for the CY8CKIT-048 PSoC® Analog Coprocessor Pioneer Kit board. These adjusts the device permissions to be accessible by non-root users.
For this create the 49-hid-development.rules
file:
$sudo vim /etc/udev/rules.d/49-hid-development.rules
with the following content:
# Cypress CY3240-I2C USB Bridge
SUBSYSTEM=="usb", ATTR{idVendor}=="04b4", ATTR{idProduct}=="f232", MODE="664", OWNER="1000", GROUP="0"
SUBSYSTEM=="usb", ATTR{idVendor}=="04b4", ATTR{idProduct}=="f147", MODE="664", OWNER="1000", GROUP="0"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", MODE="0664", GROUP="plugdev"
A restart is needed for the changes to became effective:
sudo reboot now
To build the project, first install the required dependencies:
$ sudo apt-get install libtool libhidapi-libusb0 libhidapi-dev
than clone the project from my GitHub repository:
$ git clone https://github.com/bluetiger9/cypress-usb-i2c-bridge.git && cd cypress-usb-i2c-bridge.git
Configure the project:
$ libtoolize --force && aclocal && autoheader && automake --force-missing --add-missing && autoconf && ./configure
and now the code is ready to be compiled running make
.
But wait a moment. There is a main.c
file in the src
directory:
#include ...
/* replace with the sensor data struct your application */
typedef struct __attribute__((packed)) {
uint16_t soilResistance;
int16_t temperature;
uint16_t humidity;
uint16_t illuminance;
} sensor_data;
int main(int argc, char *argv[]) {
int iface_num = 0;
int retry;
void *handle = 0;
uint16_t length = 0;
sensor_data sensorData;
// Initialize the device
cy3240_factory(
&handle,
iface_num,
50,
CY3240_POWER_3_3V,
CY3240_BUS_I2C,
CY3240_CLOCK__100kHz
);
// Open the device
cy3240_open(handle);
usleep(SLEEP_BETWEEN_CMD);
// Configure the bridge controller using the default settings
cy3240_reconfigure(
handle,
CY3240_POWER_3_3V,
CY3240_BUS_I2C,
CY3240_CLOCK__100kHz);
usleep(SLEEP_BETWEEN_CMD);
length = sizeof(sensorData);
while (true) {
// read data from your application
cy3240_read(handle, 0x08, (uint8_t*) &sensorData, &length);
// print_buffer(data, length); // uncomment this to see the raw data
// print it to stdout
fprintf(stdout, "data: %d %.2f %.2f %d\n",
sensorData.soilResistance, sensorData.temperature / 100.0,
sensorData.humidity / 10.0, sensorData.illuminance);
usleep(SLEEP_BETWEEN_CMD);
}
...
We need to edit this first according to what kind of data we are publishing from our application.
For example, my project publishes a struct of 4 sensors values: soil resistance (moisture), temperature, humidity and illuminance:
typedef struct __attribute__((packed)) {
uint16_t soilResistance;
int16_t temperature;
uint16_t humidity;
uint16_t illuminance;
} sensor_data;
Copy this struct, as it is, from your PSoC Creator project.
We also need to edit the code that prints the data, according to what fields we have:
// print it to stdout
fprintf(stdout, "sensor data: %d %.2f %.2f %d\n",
sensorData.soilResistance, sensorData.temperature / 100.0,
sensorData.humidity / 10.0, sensorData.illuminance);
The code now can be compiled with make
:
$ make
Now we can check the application works:
$ ./cy340_i2c
data: 4652 23.90 78.50 0
data: 4720 23.80 78.80 6
data: 4689 23.80 78.50 6
data: 4652 23.80 78.50 16
If yes, we can add some timestamps with the ts
command, redirect the output to a file and run the application with nohup
, so the application will keep running after we log out from SSH:
nohup stdbuf -oL -eL ./cy3240_i2c | ts '[%Y-%m-%d %H:%M:%S]' > ../sensor-data.log 2>&1 &
The output will file will look something like:
$ cat ../sensor-data.txt
...
[2017-02-06 20:54:49] sensor data: 4652 23.90 78.50 0
[2017-02-06 20:54:50] sensor data: 4720 23.80 78.80 6
[2017-02-06 20:54:51] sensor data: 4689 23.80 78.50 6
[2017-02-06 20:54:52] sensor data: 4652 23.80 78.50 16
...
Now you can let the application the running 24/7. After some time, process the file and plot data in a chart, for example.
Enjoy! :-)
Comments