Page 2 of 3
Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino
Posted: Wed Jan 27, 2016 9:56 am
by tito-t
hello davenull + Gordon + all,
thank you all for your help! I meanwhile tried this
Code: Select all
for (cnt=0; cnt<30; ++cnt ) {
recvbuf[cnt]=wiringPiI2CRead (ard_due) ;
}
Although it read and displayed 30 values on the Rpi, I encountered 2 issues:
1st, it always read just the first array value[0] == 255, but 30 times, no array[1] or [2] or [29] or what ever
2nd, after having done this 2 or 3 times, the i2c connection breaks and the Rpi does not find the Arduino any more. i2c device list on the Rpi is empty. After restarting the Arduino, it's there again (0x04).
Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino
Posted: Wed Jan 27, 2016 10:04 am
by gordon@drogon.net
tito-t wrote:hello davenull + Gordon + all,
thank you all for your help! I meanwhile tried this
Code: Select all
for (cnt=0; cnt<30; ++cnt ) {
recvbuf[cnt]=wiringPiI2CRead (ard_due) ;
}
Although it read and displayed 30 values on the Rpi, I encountered 2 issues:
1st, it always read just the first array value[0] == 255, but 30 times, no array[1] or [2] or [29] or what ever
2nd, after having done this 2 or 3 times, the i2c connection breaks and the Rpi does not find the Arduino any more. i2c device list on the Rpi is empty. After restarting the Arduino, it's there again (0x04).
For this sort of thing to work, the code on the Arduino needs to co-operate. In particular, doing it this way will send 30 STARTs to the Arduino. If the Arduino code can cope with this, then great, but if the arduino code tries to send 30 bytes in response to a single START then things will go wrong.
I've observed that the Pi's I2C hardware stack is somewhat fragile too - we all know it's not good with clock stretching, but I've also managed to cause a Pi to lock-hard (requiring a power cycle) with rogue Arduino I2C code...
If you want to read 30 bytes from an Arduino via I2C then you need to code the Arduino in such a way to send one byte at a time using that method (and you need some means to synchronise the Arduinos internal data pointer to that 30-byte array) OR you use the read() system call on the Pi end. That will send a single START then expect 30 bytes to be sent. The Arduino side needs to send those 30 bytes in response to the START on the bus.
I2C coding is horrible like that - that's why I always strongly recommend using serial if possible. (Not possible if you want to address 100 Arduinos though, however then you'll have more issues - good luck!)
-Gordon
Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino
Posted: Wed Jan 27, 2016 10:09 am
by tito-t
thank you, Gordon,
as for the Arduino slave, the corresponding Arduino MASTER code works fine and both go fine together:
Code: Select all
// Wire Master Reader
// by Nicholas Zambetti <http://www.zambetti.com>
// Demonstrates use of the Wire library
// Reads data from an I2C/TWI slave device
// Refer to the "Wire Slave Sender" example for use with this
// Created 29 March 2006
// This example code is in the public domain.
#include <Wire.h>
void setup() {
Wire.begin(); // join i2c bus (address optional for master)
Serial.begin(9600); // start serial for output
}
void loop() {
Wire.requestFrom(8, 6); // request 6 bytes from slave device #8
while (Wire.available()) { // slave may send less than requested
char c = Wire.read(); // receive a byte as character
Serial.print(c); // print the character
}
delay(500);
}
it also sends just "require 30 bytes" commands to the Arduino slave, and that works!
So how will the ported Rpi code have to look like to your opinion? Or how will have dav's code to be changed for the array receiving?
Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino
Posted: Wed Jan 27, 2016 10:23 am
by gordon@drogon.net
tito-t wrote:thank you, Gordon,
as for the Arduino slave, the corresponding Arduino MASTER code works fine and both go fine together:
Code: Select all
// Wire Master Reader
// by Nicholas Zambetti <http://www.zambetti.com>
// Demonstrates use of the Wire library
// Reads data from an I2C/TWI slave device
// Refer to the "Wire Slave Sender" example for use with this
// Created 29 March 2006
// This example code is in the public domain.
#include <Wire.h>
void setup() {
Wire.begin(); // join i2c bus (address optional for master)
Serial.begin(9600); // start serial for output
}
void loop() {
Wire.requestFrom(8, 6); // request 6 bytes from slave device #8
while (Wire.available()) { // slave may send less than requested
char c = Wire.read(); // receive a byte as character
Serial.print(c); // print the character
}
delay(500);
}
it also sends just "require 30 bytes" commands to the Arduino slave, and that works!
So how will the ported Rpi code have to look like to your opinion? Or how will have dav's code to be changed for the array receiving?
That arduino code looks like it wants to read 6 bytes from another I2C device. To do that on the Pi:
Code: Select all
unsigned char buffer [6] ;
...
read (fd, buffer, 6) ;
where fd is the file descriptor returned by a call to wiringPiI2CSetup()
-Gordon
Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino
Posted: Wed Jan 27, 2016 10:39 am
by tito-t
o yes, this Arduino code was the 6 bytes example. But davenull already also posted another code using 30 bytes by a read command which also failed. So to have finally 1 complete code which establishes byte array sending and receiving alternatingly would be fine to have eventually...

UART for Arduino is not easy to do because UART and USB ports are already in use and the Arduino USB is needed for the serial window during runtime.
Or do I understand you correctly that not even you are able to write code like for the Arduino master which works for the Rpi because the Rpi i2c is such a total crap?

Sort of a Rpi Wire() lib which mimics the Arduino Wire() lib?

Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino
Posted: Wed Jan 27, 2016 10:57 am
by gordon@drogon.net
tito-t wrote:o yes, this Arduino code was the 6 bytes example. But davenull already also posted another code using 30 bytes by a read command which also failed. So to have finally 1 complete code which establishes byte array sending and receiving alternatingly would be fine to have eventually...

UART for Arduino is not easy to do because UART and USB ports are already in use and the Arduino USB is needed for the serial window during runtime.
Or do I understand you correctly that not even you are able to write code like for the Arduino master which works for the Rpi because the Rpi i2c is such a total crap?

Sort of a Rpi Wire() lib which mimics the Arduino Wire() lib?

Not sure what you're saying here, but to read 30 bytes, just change the 6 into 30 ... I've given you the code, I don't need to re-write it... It should work - providing the Arduino slave device and the Pi agree on the means to transfer data. I2C gives you the means (OSI layers 1,2 & 3) but not the protocol (layers 4 and up). That's up to you. A lot of little devices, sensors, etc. use a register/data type of mechanism. Some simply provide data and expect you to always read the right number of bytes (which is what this case looks like) some expect you to send a fixed number of bytes, then read a fixed number, and so on. You need to know how the slave device works before writing any master code to talk to it.
I've no plans to write a Pi "Wire" library for 2 reasons: One is that it would not work well with the Linux kernel driver and 2. I don't use the Arduino wire library myself. I wrote my own implementation. (in C, not C++)
-Gordon
Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino
Posted: Wed Jan 27, 2016 11:27 am
by tito-t
no, what I wanted to say was: no single code works, neither using read nor using wiringPiI2CRead.
All things are totally messed up, either I get just 1 byte or 30 identical (not incrementing the array counter). But nevertheless, if I use Arduino code by the Wire lib, everything works always fine: the slave works fine and the master works fine. So the reason must be a totally muddled-up Rpi i2c functionality. That's why I asked if it's not possible to hae a Wire lib for Rpi which works as fine as the Wire lib on Arduino. In case the i2c implementation to Linux is faulty, then that will have to be fixed before of course.
Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino
Posted: Wed Jan 27, 2016 11:55 am
by gordon@drogon.net
tito-t wrote:no, what I wanted to say was: no single code works, neither using read nor using wiringPiI2CRead.
All things are totally messed up, either I get just 1 byte or 30 identical (not incrementing the array counter). But nevertheless, if I use Arduino code by the Wire lib, everything works always fine: the slave works fine and the master works fine. So the reason must be a totally muddled-up Rpi i2c functionality. That's why I asked if it's not possible to hae a Wire lib for Rpi which works as fine as the Wire lib on Arduino. In case the i2c implementation to Linux is faulty, then that will have to be fixed before of course.
I'm confident that the read() mechanism works. I've just done this to test:
Connect Gertduino to Pi - this has an Atmega m48p which is pretending to be an RTC. It expects the host to read 16 bytes at a time.
Write a test program:
Code: Select all
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <wiringPi.h>
#include <wiringPiI2C.h>
#include <errno.h>
#include <string.h>
int main (void)
{
int fd, i ;
unsigned char data [16] ;
if ((fd = wiringPiI2CSetup (0x68)) < 0)
{
fprintf (stderr, "Can't open RTC: %s\n", strerror (errno)) ;
exit (EXIT_FAILURE) ;
}
for (;;)
{
read (fd, data, 16) ;
for (i = 0 ; i < 16 ; ++i)
printf (" %02X", data [i]) ;
printf ("\n") ;
sleep (1) ;
}
return 0 ;
}
and run it:
Code: Select all
00 00 00 00 00 00 00 00 00 00 00 00 56 AE A8 56
00 00 00 00 00 00 00 00 00 00 00 00 57 AE A8 56
00 00 00 00 00 00 00 00 00 00 00 00 58 AE A8 56
00 00 00 00 00 00 00 00 00 00 00 00 59 AE A8 56
00 00 00 00 00 00 00 00 00 00 00 00 5A AE A8 56
00 00 00 00 00 00 00 00 00 00 00 00 5B AE A8 56
00 00 00 00 00 00 00 00 00 00 00 00 5C AE A8 56
00 00 00 00 00 00 00 00 00 00 00 00 5D AE A8 56
00 00 00 00 00 00 00 00 00 00 00 00 5E AE A8 56
00 00 00 00 00 00 00 00 00 00 00 00 5F AE A8 56
00 00 00 00 00 00 00 00 00 00 00 00 60 AE A8 56
00 00 00 00 00 00 00 00 00 00 00 00 61 AE A8 56
00 00 00 00 00 00 00 00 00 00 00 00 62 AE A8 56
00 00 00 00 00 00 00 00 00 00 00 00 63 AE A8 56
00 00 00 00 00 00 00 00 00 00 00 00 64 AE A8 56
00 00 00 00 00 00 00 00 00 00 00 00 65 AE A8 56
00 00 00 00 00 00 00 00 00 00 00 00 66 AE A8 56
00 00 00 00 00 00 00 00 00 00 00 00 67 AE A8 56
00 00 00 00 00 00 00 00 00 00 00 00 68 AE A8 56
00 00 00 00 00 00 00 00 00 00 00 00 69 AE A8 56
As you see one byte is incrementing once a second - sort of what you might expect in an RTC.
Of-course the m48p is running my own I2C stack and highly tuned it is too to work with the Pi. The source is online if you want it.
-Gordon
Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino
Posted: Wed Jan 27, 2016 1:34 pm
by davenull
hey Gordon,
I can confirm what Tim wrote:
neither wiringPiI2CRead works to read from the Arduino slave (Arduino array is not incremented by read request) nor did the simple read code work which I tried.
There must be a big issue for Arduino-to-Raspi-communication.
Again, I must give up, and at least I am not able to port your Gertuino code to make it work for my Due and my Raspi.
If both devices are Arduinos, everything is ok, when the master is a Raspi, it fails.
I can also confirm Tim's observation about the crashing i2c bus - so that's not a good and reliable setup so far.
What would be needed was actually really a complete tested sample code for alternating reading arrays[30] from an Arduino slave and writing another array to an Arduino slave.
BTW, how large is the I2C buffer to Raspi? 30? 32? even more? 64? 128? or perhaps even less than 30?
For the Arduino default is 32 minus 1-2 address bytes, but I2C_Buffer_Size can be adjusted in Wire.h or twi.c (not completely sure which one).
Nevertheless, perhaps this could be an additional issue, too.
Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino
Posted: Wed Jan 27, 2016 1:47 pm
by gordon@drogon.net
davenull wrote:hey Gordon,
I can confirm what Tim wrote:
neither wiringPiI2CRead works to read from the Arduino slave (Arduino array is not incremented by read request) nor did the simple read code work which I tried.
There must be a big issue for Arduino-to-Raspi-communication.
Again, I must give up, and at least I am not able to port your Gertuino code to make it work for my Due and my Raspi.
If both devices are Arduinos, everything is ok, when the master is a Raspi, it fails.
I can also confirm Tim's observation about the crashing i2c bus - so that's not a good and reliable setup so far.
What would be needed was actually really a complete tested sample code for alternating reading arrays[30] from an Arduino slave and writing another array to an Arduino slave.
BTW, how large is the I2C buffer to Raspi? 30? 32? even more? 64? 128? or perhaps even less than 30?
For the Arduino default is 32 minus 1-2 address bytes, but I2C_Buffer_Size can be adjusted in Wire.h or twi.c (not completely sure which one).
Nevertheless, perhaps this could be an additional issue, too.
I have little inclanation to further this myself. I know that I can write code to run on an 8Mhz ATmega that will reliably get/send small blocks of data to/from a Pi. If the Arduino 'wire' library isn't up to it, then maybe someone ought to re-write that. (Which is what I did for my own projects)
I don't know about I2C buffer size but seem to have some vague memory of 32 bytes being the most the Linux kernel will handle, but I may be wrong there (and it may be the SMBus limits). It's not something I've needed to worry about.
-Gordon
Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino
Posted: Sun Jan 31, 2016 2:51 pm
by davenull
Just some hints about potential error sources.... not sure if those informations would help nevertheless...
I just encounterd 1 issue about a Due and a Mega:
First, when reading through ressources about interfacing a Raspi to Arduinos, they all (implicitely) refer to Uno-like AVR boards, and point out that i2c would work well between both boards because the Raspi has built-in pull-ups but "the Arduino" hasn't.
In fact, that is not true in general:
It's correct that the UNO has no built-in pullups, BUT THE MEGA AND THE DUE HAVE!
The Mega (AVR) has pullups to +5V and the Due (ARM) has pullups to +3.3V (on TWI(0) ).
Nevertheless, the internal Mega pullups can be disabled by a setting in avr/twi.c,
and for the Due - even if the pullups on TWI(0) can NOT be disabled - one may use TWI1 (the 2nd i2c port) instead which has NO pullups at all.
As I am currently stuck to my Raspi-Due-UART communication, I abandonded my I2C comm attempts.
But if (e.g. Gordon...?) would provide some good working code for alternatingly exchanging raw arrays of bytes between Raspi and (either) Arduino I would gladly try to find out if there were issues about Due and Mega which could be fixed by that.
@Gordon: about your last post saying
I have little inclanation to further this myself.
after all, " little inclination" would not compulsorily mean "NO inclination" , so perhaps there would still be a little space for hope for future developments and enhancements, what do you think...?

Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino
Posted: Sun Jan 31, 2016 3:24 pm
by gordon@drogon.net
davenull wrote:
As I am currently stuck to my Raspi-Due-UART communication, I abandonded my I2C comm attempts.
But if (e.g. Gordon...?) would provide some good working code for alternatingly exchanging raw arrays of bytes between Raspi and (either) Arduino I would gladly try to find out if there were issues about Due and Mega which could be fixed by that.
@Gordon: about your last post saying
I have little inclanation to further this myself.
after all, " little inclination" would not compulsorily mean "NO inclination" , so perhaps there would still be a little space for hope for future developments and enhancements, what do you think...?

I think the issue is that the "Wire" library for Arduino is a decent bit of code, but one that is very generic, so is possibly a little bit slower than it could be. I think this introduces clock stretching which the Pi doesn't like. For me to check, I'd need to use the Arduino Wire library. I am not a fan of c++ in embedded controllers (actually, not a fan of c++ at all), so my enthusiasm to test something using the Arduino librarys is somewhat diminished.
My own library of things for microcontrollers was written from scratch some years back - I have a tiny task scheduler with librarys for serial, spi and 2-wire (i2c) as well as the analog systems, etc. This came about as I did some commercial work for someone who did not want to use GPL software at the time. However I've since used it in many other (commercial) projects both AVR and PIC - and culled out bits of it for e.g. the m48p code in the Gertduino board, so it's effectively dual-licensed. Normally I take my "reference" base and cut bits out and modify accordingly for the various projects I've worked on, so it's not really a plug & play type of thing, although the AVR stuff is very stable.
I keep meaning to publish it, but I'm not sure if I can face questions like: "what's a makefile" and the "how do you debug this thing" )-:
Anyway, I have provided code - see the m48p sources in the Gertduino thing with the program I wrote above.
As for the voltage thing and talking to 100 ATmegas... You know what I'd do? I'd back-end the Arduino with a Pi Zero and use Wi-Fi... The Arduino being something like one of Alex Eames RasPIO Duino boards....
http://rasp.io/duino/ (But I don't know your application, nor why you need 100 of them - or maybe that's someone else) Or I might just use a Pi Zero depending on exactly what it is you're doing. The Zero is cheaper anyway.
-Gordon
Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino
Posted: Sun Jan 31, 2016 3:36 pm
by davenull
The statement about 100 i2c devices was not my statement but Tim's (IIRC), and I personally only read it as being able to plug "up to 100 devices" (e.g., 1 Arduino and some different other ones additionally) was just a general option of i2c versus UART which is always limited to just 1 device which can be addressed at a time.
FTM I personally am fine with UART but I must admit that i2c might become a better option because the Raspi just has 1 UART port - but 2 i2c ports, and each one can address multiple devices. So I am very curious about this topic, the option to use I2C instead of UART eventually could be tempting also for my own projects.
Anyway, just about me and my Arduino programming skills:
I am using Arduinos exactly because of those easy things like the Wire and the Serial libs provided by the Arduino IDE , I - admittedly - can't figure out anything about "real C++" for programming Arduinos. So I personally would never use a "native C++ compiler" in order to program them.
Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino
Posted: Mon Feb 01, 2016 2:12 pm
by tito-t
yes for Arduinos I am also using only Arduino Sketch with all those available Arduino libraries, not a C compiler directly because that is far too complicated.
Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino
Posted: Thu Feb 04, 2016 11:19 am
by davenull
Now I like to share my Arduino i2c slave code which works fine with an Arduino Master.
Now we would need someone who is able to write Raspberry C code which first sends a 30 byte array to the Arduino and then reads a 30 bytes array from the Arduino.
No one able to do that?
Code: Select all
// Arduino code to send/receive byte arrays
// Arduino as an I2C slave
// compiles for MEGA and DUE, IDE 1.6.5
// ver. 0.001a
// debug mode added
#include <Wire.h>
#define SLAVE_ADDRESS 0x04
#define MSGSIZE 30
byte recvarray[MSGSIZE]; // 0=0xff; 1=chksum; ...data...; MSGSIZE-1=SLAVE_ADDRESS
byte sendarray[MSGSIZE];
volatile int8_t flag=0;
//=====================================================================================
//=====================================================================================
void setup() {
int32_t i=0;
// Serial terminal window
i=115200;
Serial.begin(i);
Serial.print("Serial started, baud=");
Serial.println(i);
// Wire (i2c)
Wire.begin(SLAVE_ADDRESS); // start Arduino as a I2C slave, addr=0x04 (7-bit coded)
Wire.onReceive(receiveData ); // event when master array is sent
Wire.onRequest(sendData ); // event when master requests array to read
memset(sendarray, 0, sizeof(sendarray) ); // init send- and recv arrays
memset(recvarray, 0, sizeof(recvarray) );
Serial.print("I2C init: my slave address= ");
Serial.println(SLAVE_ADDRESS);
Serial.println("I2C init: done.");
Serial.println();
Serial.println("setup(): done.");
}
//=====================================================================================
uint8_t calcchecksum(uint8_t array[]) {
int32_t sum=0;
for(int i=2; i<MSGSIZE; ++i) sum+=(array[i]);
return (sum & 0x00ff);
}
//=====================================================================================
void loop()
{
char sbuf[128];
Serial.println(); Serial.println();
// do something with the received data
// and then do something to build the sendarray [3]...[MSG_SIZE-2]
if (flag==1) {
//debug
sendarray[4] +=1;
}
sendarray[0] = 0xff; // 0 = start: 0xff == msg start flag
sendarray[2] = flag; // 2 = send back msg error flag
sendarray[MSGSIZE-1] = SLAVE_ADDRESS; // end of array: ID check
sendarray[1] = calcchecksum(sendarray); // 1 = calc new chksum
flag=0;
// debug output
sprintf(sbuf, "Sendarr[4]=%4d, [5]=%4d, Recvarr[4]=%4d, [5]=%4d",
sendarray[4], sendarray[5], recvarray[4], recvarray[5]) ;
Serial.println(sbuf);
delay(2); // short break for the cpu and the bus
}
//=====================================================================================
void receiveData(int byteCount) {
int32_t i;
byte val;
while(Wire.available()<MSGSIZE) ; // wait for all bytes to complete
i=0; // init counter var
while(Wire.available()&& (i<MSGSIZE) ) // read all recv array bytes
{
val=Wire.read();
recvarray[i++]=val;
}
// check for transmission error
if( (recvarray[0] == 0xff)
&& (recvarray[1] == calcchecksum(recvarray))
&& (recvarray[MSGSIZE-1] == SLAVE_ADDRESS ) )
flag=1; // data ok
else
flag=127; // data faulty => handle rcv-error => flag =127
}
//=====================================================================================
void sendData(){
// Wire.write writes data from a slave device in response to a request from a master
Wire.write(sendarray, MSGSIZE); // send own byte array back to master..
}
//=====================================================================================
Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino
Posted: Fri Feb 05, 2016 11:51 am
by tito-t
thank you! But now I am totally bewildered - no one around here in this forum full of experts who is able to write Raspberry C code to send and receive arrays to/from an Arduino!? That is embarassing.... So do I really have to abandon this and have to use multiple PCFs and MCPs instead? That cannot be true to be honest....

Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino
Posted: Fri Feb 05, 2016 12:33 pm
by gordon@drogon.net
tito-t wrote:thank you! But now I am totally bewildered - no one around here in this forum full of experts who is able to write Raspberry C code to send and receive arrays to/from an Arduino!? That is embarassing.... So do I really have to abandon this and have to use multiple PCFs and MCPs instead? That cannot be true to be honest....

There are many people who're experts in this field, however some of us have other things to do. If you're building such a large system, then it sounds fairly commercial... Why notpay someone to do it for you?
(No, I'm not offering - busy enough right now)
-Gordon
Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino
Posted: Fri Feb 05, 2016 12:37 pm
by joan
tito-t wrote:thank you! But now I am totally bewildered - no one around here in this forum full of experts who is able to write Raspberry C code to send and receive arrays to/from an Arduino!? That is embarassing.... So do I really have to abandon this and have to use multiple PCFs and MCPs instead? That cannot be true to be honest....

You don't need an expert. You need to acquire basic programming skills, one of which is to read documentation.
From C open the /dev/i2c-1 device, use an IOCTL to select the I2C address, write 30 bytes. Job done.
Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino
Posted: Fri Feb 05, 2016 1:43 pm
by tito-t
it's not a large system, it's just for a mobile robot with 8 sharp IR distance sensors and a couple of rotary encoder motors plus a Pixy cam plus a couple of bumper sensors (touch buttons). At first I wanted to use 2 PCF8591 for the analog sensors and 1 or 2 MCP23017 for the touch sensors and the encoders plus 1 Arduino Uno to interface the Pixy Cam and 1 or 2 more UART sensors (via softserial). But then Davenull's idea about a Arduino Due seemed to be even a better idea. But I had to interface 1 Arduino in either case. The problem seems to read 30 bytes from the Arduino, not to write, but I am a beginner and just used to Arduino IDE Sketches where everything is so easy and comfortable. I have no idea about IOCTL and the low level C coding, I thought the Rpi was made for beginners and hobbyists like the Arduino, not for specialists. This all looks awfully complicated. If I only had a simple code to start with (simply first read and then write an array to an Arduino)! I tried davenull's code for reading 30 bytes from the Arduino which he posted above and I failed completely, and he, too, as he wrote. So it appears not to be just trivial.
Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino
Posted: Fri Feb 05, 2016 3:16 pm
by gordon@drogon.net
tito-t wrote:it's not a large system, it's just for a mobile robot with 8 sharp IR distance sensors and a couple of rotary encoder motors plus a Pixy cam plus a couple of bumper sensors (touch buttons). At first I wanted to use 2 PCF8591 for the analog sensors and 1 or 2 MCP23017 for the touch sensors and the encoders plus 1 Arduino Uno to interface the Pixy Cam and 1 or 2 more UART sensors (via softserial). But then Davenull's idea about a Arduino Due seemed to be even a better idea. But I had to interface 1 Arduino in either case. The problem seems to read 30 bytes from the Arduino, not to write, but I am a beginner and just used to Arduino IDE Sketches where everything is so easy and comfortable. I have no idea about IOCTL and the low level C coding, I thought the Rpi was made for beginners and hobbyists like the Arduino, not for specialists. This all looks awfully complicated. If I only had a simple code to start with (simply first read and then write an array to an Arduino)! I tried davenull's code for reading 30 bytes from the Arduino which he posted above and I failed completely, and he, too, as he wrote. So it appears not to be just trivial.
I did provide an example above that works. Link to it here:
viewtopic.php?p=893501#p893501
The issue as far as I can tell is that the Arduino Wire library does not appear to be good enough for the Pi. I do not use the Arduino Wire library in my ATmega projects. There are known limitations to the Pi's I2C hardware and not everything works. I can make Arduinos work with the Pi but I had to write my own I2C code on the Arduino to do that. (That code is also published if you're interested - I did provide links for it earlier - however it may not work in Arduino world as I don't use that either)
If you want it easy, then code in Python.
wiringPi (a library for C/C++ programs) supports the pcf8591 and mcp23017 chips directly. You do not need to do anything with I2C for these as wiringPi (ie. me!) does it for you. You just initialise the chips with a single function call, then use pinMode(), digitalRead(), digitalWrite(), analogRead() and analogWrite() as usual.
Sometimes it's really not easy though. Sometimes you actually have to learn how to do something. I do not think that the Arduino environment is a good learning environment as it does far too much for you - resulting in the "Waaah" situation when you move to a different system.
The Pi is a computer that lets you develop and test code directly on the computer, It's cheap, but you won't magically learn anything just by owning one.
If I have time this weekend I will try to put something together to test this, but no promises. I will use my code above, unmodified, on the Pi. I am convinced that it's the Arduino side where the issues are.
But I still say use serial - its far easier to manage. Faster too.
-Gordon
Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino
Posted: Fri Feb 05, 2016 3:32 pm
by tito-t
thank you Gordon, am I right that then the code for the Rpi should look like that?
Code: Select all
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <wiringPi.h>
#include <wiringPiI2C.h>
#include <errno.h>
#include <string.h>
int main (void)
{
int fd, i ;
unsigned char data [30] ;
if ((fd = wiringPiI2CSetup (0x04) ) < 0)
{
fprintf (stderr, "Can't open RTC: %s\n", strerror (errno)) ;
exit (EXIT_FAILURE) ;
}
for (;;)
{
read (fd, data, 30) ;
printf ("read: ");
for (i = 0 ; i < 30 ; ++i)
printf (" %3d", data [i]) ;
printf ("\n") ;
sleep (1) ;
write(fd, data, 30) ;
printf ("write: ");
for (i = 0 ; i < 30 ; ++i)
printf (" %3d", data [i]) ;
printf ("\n") ;
sleep (1) ;
}
return 0 ;
}
Anyway, I'm almost sort of reassured to hear from you that there are severe Rpi and Arduino issues to i2c and that this problem is not just a simple "read the f... manual" thing as I read above - instead it actually appears really to be a specialist's task to make that work. Anyway I'm very happy that you - perhaps - will try to establish a code from Rpi to Arduino Sketch which - perhaps - even would work.

I'm gladly looking forward to it, thanks for your efforts!
[edited to remove swearing. please don't use curse words in the forums]
Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino
Posted: Fri Feb 05, 2016 4:57 pm
by gordon@drogon.net
tito-t wrote:thank you Gordon, am I right that then the code for the Rpi should look like that?
Looks ok, but only you can test it... You have to be absolutely sure that the Arduino end will send 30 and only 30, no more and no less bytes when the Pi requests it.
Anyway, I'm almost sort of reassured to hear from you that there are severe Rpi and Arduino issues to i2c and that this problem is not just a simple "read the f... manual" thing as I read above - instead it actually appears really to be a specialist's task to make that work. Anyway I'm very happy that you - perhaps - will try to establish a code from Rpi to Arduino Sketch which - perhaps - even would work.

I'm gladly looking forward to it, thanks for your efforts!
I'd not go as far as to say
severe issues - it's just one feature that the Pi doesn't support (clock stretching). This manifests itself when a slave device is unable to process data in a timely manner, however I think (from vague memories) that the Arduino wire library isn't that quick on doing what it needs to do to acknowledge data, which results in a clock stretch. My own code which doesn't rely on the Arduino Wire library works fine - but if you want to use that, you'll need to throw away all the Arduino coziness and use a proper editor and Makefiles.. (actually, you could incorporate it into a "sketch" if you knew how to, but hey)
-Gordon
Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino
Posted: Fri Feb 05, 2016 5:05 pm
by joan
gordon@drogon.net wrote:
...
I'd not go as far as to say severe issues - it's just one feature that the Pi doesn't support (clock stretching).
...
I understand the lack of support for clock stretching is down to the current driver rather than the Pi hardware.
I remember a forum post where someone had tested their own I2C driver with clock stretching and had done a push or pull or whatever to try to get the update included.
Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino
Posted: Fri Feb 05, 2016 5:56 pm
by gordon@drogon.net
joan wrote:gordon@drogon.net wrote:
...
I'd not go as far as to say severe issues - it's just one feature that the Pi doesn't support (clock stretching).
...
I understand the lack of support for clock stretching is down to the current driver rather than the Pi hardware.
I remember a forum post where someone had tested their own I2C driver with clock stretching and had done a push or pull or whatever to try to get the update included.
That's interesting - be good to know for sure. I was chatting with Gert once and he was the one who explained to me that it simply didn't work in the hardware side of it - the Pi keeps on outputting clock (& data) pulses even when the slave holds the clock low... Maybe it bit-bangs it - at the bit level rather than using the SoC hardware driver? That ought to be possible...
-Gordon
Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino
Posted: Fri Feb 05, 2016 6:04 pm
by joan
gordon@drogon.net wrote:
...
That's interesting - be good to know for sure. I was chatting with Gert once and he was the one who explained to me that it simply didn't work in the hardware side of it - the Pi keeps on outputting clock (& data) pulses even when the slave holds the clock low... Maybe it bit-bangs it - at the bit level rather than using the SoC hardware driver? That ought to be possible...
-Gordon
This is the post I was thinking of.
viewtopic.php?p=870098#p870098