GrovePi+ and C programming


#1

Is anybody programming in c on the Raspberry Pi2 and interfacing with the GrovePI+? I don’t see any documentation for c programmers.
thanks!


#2

Hey,
We are working on a basic library for the C support. It’is not going to be full fledged but it should have most of the basic C functions. We’ll release it probably by the end of this week. Can you check back https://github.com/DexterInd/GrovePi/tree/master/Software/C in a week.

-Karan


#3

I just checked the github and I don’t see the library yet? Do you have an ETA for the library? I have a Grove Gesture Sensor and a I2C Motor Driver and neither works with the RPi2 and Grove Pi+.
Kinda disappointed as I am on a schedule… :frowning:

thanks!


#4

Karan
Is there a chance I can get an early release?

thanks!


#5

Hey roujesky,
I’ll try pushing the code code today or tomorrow. But it would be a very basic code with just analog read working. But all the low level things are done, so you can easily build on top of it for other functions. But it is still unstable and might have bugs too. Would that work. What all do you need working in C for your project.

-Karan


#6

I am trying to get the Gesture board and I2C Motor Driver to work. I am failing miserably… Really, I am a pretty good programmer/engineer, but I am struggling. :slight_smile:

thanks!


#7

so ? :slight_smile:


#8

Sorry for taking this long to reply back.

We just released the C code for the GrovePi. Here is the link to it: https://github.com/DexterInd/GrovePi/tree/master/Software/C. It is still in a very early stage and any feedback is greatly appreciated.

-Karan


#9

I am using the C code you provided to create a port of the grove_led_blink.py in C. Here is my code, which is basically working. But from time to time, I get some input/output errors when calling digitalWrite. The example in Python works perfectly on my Pi. Is there something wrong with my code or what is the origin of this problem? Could there be a problem with clock stretching?

Here’s my code:


#include "grovepi.h"
#include <stdlib.h>

#define PIN_INPUT     0
#define PIN_OUTPUT    1

#define LED           4

int main(void)
{
        int i;

        init();
        pinMode(LED, PIN_OUTPUT);
        usleep(100000);

        puts("This example will blink a Grove LED"
             "connected to the GrovePi+ on the port labeled D4.\n"
             "If you're having trouble seeing the LED blink,"
             "be sure to check the LED connection and the port number."
             "You may also try reversing the direction"
             "of the LED on the sensor.\n"
             "Connect the LED to the port labeled D4!\n");
        usleep(5000000);

        for (i = 0; i < 300; i++)
        {
                // Blink the LED
                digitalWrite(LED, 1);    // Send HIGH to switch on LED
                puts("LED ON!");
                usleep(1000000);

                digitalWrite(LED, 0);   // Send LOW to switch off LED
                puts("LED OFF!");
                usleep(1000000);
        }

        return EXIT_SUCCESS;
}


#10

Hi,
A few IO errors are expected when reading the data off the GrovePi. Can you paste the output that you get here so that we can look into it.

-Karan


#11

I added errno.h and some lines of code in the function write_block() for error checking:

if ((dg=i2c_smbus_write_i2c_block_data(fd,1,4,w_buf)) != 0)
{
	    printf("ERROR: Unable to write block to GrovePI. %s\n",
	           strerror(errno));
    	errno = 0; // reset errno
}

and get the following output when running the program

[...]
LED ON!
LED OFF!
LED ON!
ERROR: Unable to write block to GrovePI. Input/output error
LED OFF!
LED ON!
LED OFF!
[...]

These errors appear randomly on calls to i2c_smbus_write_i2c_block_data.

You mentioned that a few I/O errors are expected. When using the code above, I get 6-10 I/O errors when calling the write_block function a thousand times. Is this still normal?

blubb

#12

Hi blubb,
We have seen this in python but we were not expecting the C code to throw these many IOErrors. Are you using GrovePi+. Can you add a picture of it. Also, can you try running this and checking what is the firmware version on the GrovePi: https://github.com/DexterInd/GrovePi/blob/master/Software/Python/grove_firmware_version_check.py.

-karan


#13

Hello karan

I am pretty sure, I am using the GrovePi+, but I added a Picture anyway.
The given script was telling me, I am using firmware version 1.2.2. I recently updated to this version. The C-code I want to use, also didn’t work with a previous firmware version.

blubb


#14

Hey,
Can you try using firmware version 1.2.5 from here: https://github.com/DexterInd/GrovePi/tree/master/Firmware/Source/v1.2/grove_pi_v1_2_5. Use avrdude -c gpio -p m328p -U flash:w:grove_pi_v1_2_5.cpp.hex to burn it. The use grove_firmware_version example to check that you are on v1.2.5 and then try running hte examples again to see if the errors go away.

-Karan


#15

Hi karan

I installed the firmware version 1.2.5. The output of the grove firmware version check is telling me, I was successful. Unfortunately, the examples are still not working properly, and giving me the same errors as before the firmware update.

blubb


#16

Hey blubb,
Do you still get ERROR: Unable to write block to GrovePI. Input/output error. How often does it come and does the GrovePi still work after the error is gone. The C examples are still in development so it might take some time to get them working properly.

-Karan


#17

Hello Karan

Yes, there are still the same error messages. I tried to call the write_block() function 20,000 times. 136 times the function failed because of an input/output error. The GrovePi is still working after an error.

I am aware of this fact. I am not a professional C developer and doing this just for fun. Please let me know, if I can help or test something.

blubb


#18

Hey blubb,
Thanks for the information. Are you still using the same program that you had pasted in the post above. These many IOErrors are pretty much expected. I’ll test the program later this week and let you know how it goes.

-Karan


#19

Hi Karan

I currently using the provided grovepi.h and a modified version of grovepi.c from Dexter Industries.
I made two changes in grovepi.c. On one side I added an external variable which is declared global and defined in my C code. On the other hand, I changed the write_block() function.

/* grovepi.c */

// global variable for counting errors
extern int error_count;

// modified version of write_block
int write_block(char cmd,char v1,char v2,char v3)
{			
    int dg;
    w_buf[0]=cmd;
    w_buf[1]=v1;
    w_buf[2]=v2;
    w_buf[3]=v3;
	
    if ((dg=i2c_smbus_write_i2c_block_data(fd,1,4,w_buf)) != 0)
    {
        printf("ERROR: Unable to write block to GrovePI. %s\n",
	       strerror(errno));
        error_count++;
        errno = 0; // reset errno
    }
	
    if (dbg)
        printf("wbk: %d\n",dg);

    return 1; 
}

And here is the current code I am using for testing:

/* test.c */

#include "grovepi.h"
#include <stdlib.h>

#define PIN_INPUT     0
#define PIN_OUTPUT    1

#define LED           4

int error_count = 0;

int main(void)
{
	int i;
	
	init();
	pinMode(LED, PIN_OUTPUT);
	usleep(100000);
		
	puts("This example will blink a Grove LED"
	     "connected to the GrovePi+ on the port labeled D4.\n"
	     "If you're having trouble seeing the LED blink,"
	     "be sure to check the LED connection and the port number."
	     "You may also try reversing the direction"
	     "of the LED on the sensor.\n"
	     "Connect the LED to the port labeled D4!\n");
	usleep(5000000);

	for (i = 0; i < 5000; i++)
	{
		// Blink the LED
		digitalWrite(LED, 1);    // Send HIGH to switch on LED
		puts("LED ON!");
		usleep(100000);

		digitalWrite(LED, 0);   // Send LOW to switch off LED
		puts("LED OFF!");
		usleep(100000);
	}
	
	printf("Write procedures: %d\n"
	       "Error counter: %d\n",
	       i*2, error_count);       // Multiply i * 2, because
                                        // we are writing two times to
                                        // the grovepi, before
                                        // incrementing i.

	
	return EXIT_SUCCESS;
}

I am compiling and testing on a Raspberry PI 2 using GCC version 4.9.2 on Raspbian Jessie, using the command
gcc -o test test.c grovepi.c -Wall

Probably the sleep period between the calls to the digitalWrite function are too short (0,1 second). I am testing now with longer wait phase and will inform you, if the rusults are sicnificantly differnt.
-> The result didn’t change. 10.000 write sequences created 65 errors.

Blubb


#20

I have exactly the same problem.
The fragment of code I use to send a command to GrovePi looks like:

void
GrovePi::sendBuf(unsigned char * buf, int bufLen) const throw() {
    int rc;
        
    rc = write(file, buf, bufLen);
    if (rc != bufLen) {
        std::cout << "Can't send buffer to controller rc=" << rc <<" bufLen=" << bufLen << std::endl;
        std::cout << "Error: " << strerror(errno) << std::endl;
        throw(gpEx);
    }

What am I doing wrong?

In in my case error rate is one I/O error per 30-40 commands.
Is that what I should expect?

thanks,
Igor