C programming examples?

Hi

Are there any decent examples of controlling the PicoBorg Reverse (or platforms that use it) from C code? I can find Python examples, but I have 25 years´ C development experience, and I don't want to work in Python.

Best wishes
Kevin

piborg's picture

We do not have any complete examples in C, but this forum post should point you in the right direction:
PicoborgRev C/C++ Library

I also have the same question because i'm intresting to create an app in C++ to drive PicoBorg Reverse and Pi Camera.
I've read the implementation for arduino and i want to answer the user Kevin also. The implementation of the library for Arduino seems to be perfect to use it in a C or C++ code, the only thing that need to be changed if i'm not wrong is the library for the i2c implementation. The only thing that you have to change in the code is replace the Wire.h library with the WiringPi library. If you search on google you can see that there's an inplementation of the i2c protocol in this library + all the control for the GPIO pin.

I will start the porting from Python to C++ and when i'm done, i will share the library with all the user on this forum :)

Thanks. I'm not sure that there is need to use WiringPi here -- isn't the low-level voltage-wiggling stuff done by the kernel's i2c module? If I understand correctly, it should "just" be necessary to take the Arduino code and replace the calls to Wire with ordinary read()/write() calls, once you've set the interface up.

Is that right?

I note that the Arduino code has functions for operating the PicoBorg Reverse using a (shaft?) encoder. But the board itself does not seem to have ny connections for a shaft encoder. Am I missing the point, or is additional hardware needed for this mode of operation?

Finally -- what is needed to test whether I can get basic i2c operation working? I mean, will the board actually operate with no motors connected, to the extent that at least I can query status using i2c? Does the battery connection to the board just power the motors, or does it power the logic as well?

piborg's picture

The PicoBorg Reverse can be used without any motors or battery connected.
As long as the 6-pin header is connected you should be able to talk with it using the I2C.

You should be able to use the read / write calls if you send and receive using byte buffers, that is what we have done for XLoBorg.
The easiest way to check everything is working properly would be to send the COMMAND_GET_ID message, this should then have a reply containing I2C_ID_PICOBORG_REV.

The PioBorg Reverse does not support a full encoder, but it can use one half of the pair.
The idea is it provides a means of moving a fixed distance, however it does not provide positional data via the I2C.

I'm not sure also. I can read from internet that all the example for the i2c comunication in C/C++ are with external library. For example see this link also: https://www.raspberrypi.org/forums/viewtopic.php?f=33&t=43725
I really think that we need to use a library (Also WiringPi have an header of i2c) and replace the Wire calls.
Regarding the encoder, no i don't think there are encoder on the PicoBorg Reverse.

It would be nice to get some clarity on the WiringPi issue. I've seen i2c programming examples on various websites that use this library, and others that don't. I looked at the WiringPi source, and I note that it does require that kernel i2c support is enabled, so it isn't doing its own low-level logic control. It seems to do all its work using ioctl() calls on /dev/i2c-xxx, rather than plain read()/write() calls as the PiBorg guys advised.

Is it possible that the kernel's support for i2c has changed, such that it is now possible to control the bus using plain read/write operations? I can see how using WiringPi would be advantageous if the alternative were a string of incomprehensible ioctl() calls.

Using an additional library doesn't bother me, but I rather suspect that most people who are using WiringPi for i2c stuff are doing so because it has a similar interface to the Arduino Wire library, which makes it easier to port code.

piborg's picture

It is true that support for the I2C has changed since the Raspberry Pi was released.
I am not sure exactly when the support for read / write was introduced, but I do remeber that the first version of Raspbian did not event support the ioctl calls.

The read / write functionality has been available in Raspbian for a while now, at least a couple of years.
If you do use read / write for accessing the I2C then you will need to use ioctl to set the I2C address for the board.
After that it is simply one write call per command, or one write call and one read call per query.

I think in truth it will make little difference if you use the read / write calls or if you use a library like WiringPi to access the I2C.
Hopefully you will find the messages themselves are simple enough that translating the calls should be fairly straight forward.

Thanks. Sure, it doesn't seem to be a big deal one way or the other. Just trying to make sense of the conflicting reports that Mr Google is taking me to.

Hi Lars, did you try to make the library in C++? I have a lot of problem to make it works, there is too much difference between the Wire library of Arduino and the WiringPiI2C library. Your help would be really nice!

Hiya

Only got my reverse this morning, so I haven't done much with it. However, I'm able to turn the on-board LED on and off in C code. Basically:

int f = open ("/dev/i2c-1", O_RDWR);
ioctl(f, I2C_SLAVE, 0x44); // Select the Reverse on the bus
unit8_t buff[1];
buff[0] = 1;  // Code to set LED
buff[1] = 1; // 1 = on
write (f, buff, 2);
close (f);

There may be some subtleties I'm missing, but that seems to work fine for me so far.

To be honest, the I2C commands to control the motors don't look any more complicated than this -- it's just a matter of figuring out which bytes to send, by decoding the Arduino example.

When I get the motors working (or at least my simulation of the motors, since I haven't ordered them yet), I'll try to post some proper code on my website.

Best wishes
Kevin

Hi

For the record, it really is as simple as I thought to control the motors in C. I was going to post a code example, but it's so easy that it's hardly worth it :) It's just a case of calling ioctl() as in my previous post, writing one or more bytes to the i2c device and then reading one or more bytes if the command returns data. The devil might be in the details, I guess, but this is working fine for me so far.

The only slightly tricky part is reverse-engineering the actual send and receive bytes from the Arduino example. For the record, I have attached a brief summary of the i2c protocol -- at least those bits of it I have tested.

Best wishes
Kevin

=================

Each command requires the transmission of one or two bytes; responses
are zero to two bytes.

Note "motor1" here refers the connections so labelled on this page:
https://www.piborg.org/picoborgrev/specs. Compared with PiBorg's Arduino
code, motor1=motorB, motor2=motorA. Go figure.

Get ID
Send 0x99, Receive 0x99,0x15 if correct board

Set LED status
Send 0x01,N where N=1 or 0

Get LED status
Send 0x02, receive 0x02,N where N=1 or 0

Set motor1 fwd
Send 0x6,N where N 0-255

Set motor1 rev
Send 0x7,N where N 0-255

Set motor2 fwd
Send 0x3,N where N 0-255

Set motor2 rev
Send 0x4,N where N 0-255

Get motor1 speed and direction
Send 0x08, receive 0x08,D,S where D=1 is fwd, D=2 is reverse, S is speed 0-255

Get motor2 speed and direction
Send 0x05, receive 0x05,D,S where D=1 is fwd, D=2 is reverse, S is speed 0-255

Stop all
Send 0x09

Can I connect the PicoBorg Reverse to the SDA/SCL pins of a arduino board and send signals from arduino to PicoBorg to control the motor using C?

piborg's picture

It is possible to use an Arduino Uno to control a PicoBorg Reverse:

We have an example project which includes the library to make controlling the PicoBorg Reverse as simple as it is with the Raspberry Pi.
The example has a simple demo sequence which will check it is talking with the PicoBorg Reverse correctly.
The example also includes wiring instructions for most Arduino boards and a detailed explanation of what it does in the code comments.

You can download the example here: https://www.piborg.org/downloads/picoborgrev/PicoBorgRevArduino.zip

The pins on one of the PicoBorg Reverse six-pin headers need to be connected as follows:
  • Pin 1 -> 3.3v Power for the PIC, otherwise known as 3V3, it is marked with a 1
  • Pin 2 -> Unused May be left disconnected
  • Pin 3 -> SDA I2C data line, used for communications
  • Pin 4 -> Unused May be left disconnected
  • Pin 5 -> SCL I2C clock line, used for communications
  • Pin 6 -> GND Ground, otherwise known as 0v, reference for all other lines

Cool, thank you very much. :)

Subscribe to Comments for "C programming examples?"