Raspberry/Grove Pi C API i2c write

Hi

So I’m writing against this C API with GrovePi and Raspberry Pi to control some of the more complicated sensors, using the grovepi.py i2c_write_block commands as a reference but having really no luck.

These commands work fine:
#define dRead_cmd 1
#define dWrite_cmd 2
#define aRead_cmd 3
#define aWrite_cmd 4
#define pMode_cmd 5

But if i try to use one of the others, for example:
#define ultrasonicRead_cmd 7

The value returned is always zero. The commands are just being written to the i2c_smbus whether its over python or C. So why can’t I retrieve any of this data?
I’ve follow the python code as closely as I can with regards to time delays etc.

I’ve also tried:
#define dht_temp_cmd 40

This also didn’t work, neither did using digitalWrite to try and manually pull the pin down up down up. So I moved on to try and use the bcm3825 lib to control the pins manually and got another problem: I can’t find any reference to map the Grove Pi port numbers with the literal Raspberry Pi 3 GPIO numbers? Would D4 = GPIO 4 ?

In a time constraint so any information would be greatly appreciated!

-Alex

@alex.blake:

Can you share the code that you are working on. I’ll give it a shot and see if it works .

Also the GrovePi pins are not directly mapped to the Ports. The Raspberry Pi sends commands to a Atmega328 co-processor on the GrovePi via I2C which handles the GrovePi ports.

You can find more information here and here

Hi Karan,

thanks for your quick reply. I’ve tried a lot of variations of the below for both the ultrasonic and the DHT sensor (thought the buffers were being overwritten hence some commented code, also changed the size of “data” in case it was being truncated ).
If you run the python ultrasonic, then run this one after, the first three loops read the last value python pulled three times before it clears, then nothing is returned.

Has anyone tried successfully to used the C API with commands other than the first 5 in the example ?

int ultrasonicRead(int pin)
{
int data;

	write_block(7, pin, 0, 0);

	usleep(200000);

	//u_buf[0] = i2c_smbus_read_byte(fd);
	//i2c_smbus_read_i2c_block_data(fd, 1, 32, &u_buf[0]);
	read_byte();
	read_block();


	data = r_buf[1] * 256 + r_buf[2];
	//data = u_buf[1] * 256 + u_buf[2];

	if (data == 65535)
		return -1;
	return data;
}

I suspect the i2c_smbus_write_i2c_block_data(fd, 1, 4, w_buf) command is sending or not sending some flag that the GrovePi is waiting for.

@karan Did you get a chance to try this out? Do you know if this is possible through the C API or if i should move onto java or something else?

Hi @alex.blake,

Sorry for the delay in testing things out. We have got the Ultrasonic sensor to work with the C library and its still under testing though. Can you try out the following and tell us how well it works for you.

  1. Add the highlighted lines to grovepi.h

2. Add the following code at the end of the grovepi.c file

int ultrasonicRead(int pin)
{
int data;
write_block(uRead_cmd,pin,0,0);
usleep(60);
read_byte();
read_block();
data=r_buf[1]* 256 + r_buf[2];
if (data==65535)
	return -1;
return data;

}
3. Create an example called grovepi_us_read.c with sudo nano grovepi_us_read.c to test the ultrasonic sensor and add the following lines

# include "grovepi.h"

int main(void)
{		
	int adata;
	
	//Exit on failure to start communications with the GrovePi
	if(init()==-1)
		exit(1);
	
	while(1)
	{   # Connect the ultrasonic sensor to port D4
		adata=ultrasonicRead(4);
		printf("ultasonic read %d\n",adata);
		if(adata==-1)
			printf("IO Error");
	}
   	return 1;
}

4.Connect the Ultrasonic Sensor to Port D4.
5. Run the following to execute the code
sudo gcc grovepi_us_read.c grovepi.c -Wall
./a.out

Please let us know if this helps,
-Shoban

Hi @Shoban,

Thank you very much for your answer.

This code does indeed work! The application I’m writing has a lot of complicated compilation parameters and so I moved the function definitions from grovepi.c to grovepi.h and just included grovepi.h into my application.

Like I said this worked for the first commands parameters, but none of the others.

gcc example.c grovepi.c -Wall
Works for the Ultrasonic sensor functionality.

What is the difference between compiling in this way and simply including all the C API functions as a header file?

Thanks again,

Alex

@alex.blake,
It should have worked if you had moved all the functionality in the header though it is really not recommended (read this, this and this ) . Most probably there might be some small error when you tried adding everything together.

Thanks for all your help.
I’ve fixed the problem now, not entirely sure what caused it.

I had modified char *fileName = “/dev/i2c-1”; to a string to suppress a compiler warning generated by g++, once I changed it back and supressed the warning at compile time the ultrasonic began to work.

Threw me that the first 5 commands worked while others wouldn’t.

What is the purpose of:

#define GROVEPI_H

?

Hi @alex.blake,

Glad that it worked for you. These ifndefs are called as the include gaurds and a detailed explanation of why these are important are given here and here.

Let us know if this helps,
-Shoban