Page 3 of 3

Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino

Posted: Fri Feb 05, 2016 6:40 pm
by tito-t
I will try again immediately, I will add the error checking of davenul's code to the Rpi code and also add a value incrementing (without stretching for the start) and then see and report!

Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino

Posted: Fri Feb 05, 2016 6:56 pm
by tito-t
update:
GOOD NEWS! THE CODE IS WORKING !
EXTREMELY SLOW though (1 send and 1 receive in 1 second) maybe due to transmission control and blocking of intermediate data corruption. That's great but unfortunately over all of course that's actually still FAR TOO SLOW, but anyway, at least it's already a big leap for the start! :)
I took davenul's code for the Arduino and changed the Rpi code accordingly with incrementing a debug value.
Now I'm curious if someone can give hints about making it communicate even faster:

Raspberry Pi i2c master:

Code: Select all

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <wiringPi.h>
#include <wiringPiI2C.h>

#include <errno.h>
#include <string.h>

#define MSGSIZE 30


unsigned char  calcchecksum( unsigned char array[]) {   
  int32_t  sum=0;
  for(int i=2; i<MSGSIZE; ++i) sum+=(array[i]);
  return (sum & 0x00ff);
}



int main (void)
{
	
  int fd, i ;
  unsigned char test=0; 
  unsigned char data [MSGSIZE] ;

  if ((fd = wiringPiI2CSetup (0x04) ) < 0)
  {
    fprintf (stderr, "Can't open RTC: %s\n", strerror (errno)) ;
    exit (EXIT_FAILURE) ;
  }


  for (;;)
  {
    read (fd, data, MSGSIZE) ;
    printf ("read:  ");
    for (i = 0 ; i < MSGSIZE ; ++i)
      printf ("  %3d", data [i]) ;
    printf ("\n") ;
    sleep (1) ;
   
    memset(data, 0, sizeof(data) );
    data[5]=  test++;
    data[0]=  0xff;
    data[MSGSIZE-1]= 0x04;
    data[1] = calcchecksum( data );
    
    write(fd, data, MSGSIZE) ;
    printf ("write: ");
    for (i = 0 ; i < MSGSIZE ; ++i)
      printf ("  %3d", data [i]) ;
    printf ("\n\n") ;
    sleep (1) ;
  }

  return 0 ;
}
Arduino i2c slave:

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


#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..
}

so first of all: thanks to you all who have been helping and participating!

Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino

Posted: Fri Feb 05, 2016 7:08 pm
by davenull
congratulations!
(About the speed I am curious too!) :ugeek:

ps: I tested the transmission speed of this setup both with the Raspi Master and with an Arduino Master instead:
with the Arduino master it's more than 30x faster (perhaps even slowed-down by console debug screen output) !


pps,
OT: a Pixy Cam is a good additional idea... :geek:

Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino

Posted: Sun Feb 07, 2016 4:43 pm
by davenull
aaahm: I just came upon a funny thing:

in your / Gordon's code there are 2
sleep(1);

I assumed it was millis, just like for delay, but actually it's seconds !!!

I changed it to delay(10) and now it's so fast that you'll think that you just can't trust your eyes! :D

Raspi Master Code:

Code: Select all

//  Raspberry Pi Master code to send/receive byte arrays
//  to an Arduino as an I2C slave
// 
//  ver. 0.001b

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <wiringPi.h>
#include <wiringPiI2C.h>

#include <errno.h>
#include <string.h>

#define MSGSIZE 30


unsigned char  calcchecksum( unsigned char array[]) {   
  int32_t  sum=0;
  for(int i=2; i<MSGSIZE; ++i) sum+=(array[i]);
  return (sum & 0x00ff);
}



int main (void)
{
   
  int fd, i ;
  unsigned char test=0;
  unsigned char data [MSGSIZE] ;

  if ((fd = wiringPiI2CSetup (0x04) ) < 0)
  {
    fprintf (stderr, "Can't open RTC: %s\n", strerror (errno)) ;
    exit (EXIT_FAILURE) ;
  }


  for (;;)
  {
    read (fd, data, MSGSIZE) ;
    if( data[1] != calcchecksum( data ) ) {
         // handle transmission error !
    }    
    printf ("read:  ");
    for (i = 0 ; i < MSGSIZE ; ++i)
      printf ("  %3d", data [i]) ;
    printf ("\n") ;
    delay(10);
   
    memset(data, 0, sizeof(data) );
    data[5]=  test++;
    data[0]=  0xff;
    data[MSGSIZE-1]= 0x04;
    data[1] = calcchecksum( data );
   
    write(fd, data, MSGSIZE) ;
    printf ("write: ");
    for (i = 0 ; i < MSGSIZE ; ++i)
      printf ("  %3d", data [i]) ;
    printf ("\n\n") ;
    delay(10);
  }

  return 0 ;
}
I also changed my Arduino slave code a bit from delay(2) to delay(1), that's also fine as far as I can observe!

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.001b


#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(1);                                     // 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..
}

share and enjoy! :mrgreen:

Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino

Posted: Sun Feb 07, 2016 8:04 pm
by davenull
update:
the i2c connection is quick and stable now since 2 hours. I will now try to port my UART communication code (which is already running by 64 byte arrays) to i2c.
1st I will try MSGSIZE of 31 or 32 and then maybe even more by enlarging the Arduino i2c buffer size for my DUE and my MEGA in "Wire.h"
#define BUFFER_LENGTH 32 // perhaps 64...128 ???
(hardware/arduino/sam/libraries, hardware/arduino/avr/libraries)
and then see if there are limits to the Raspi i2c buffer size.
Then I will check if different additional i2c devices will be compatible to this setup - 1st of all I will add my CMPS11 to the bus, and 2nd an additional Arduino. I'm really curious if that will work.... 8-)

Having done this it will be easy for everybody to utilize the large Arduino's 12 ADCs and ~ 50 dPins (stored as bitpatterns, 8 IOs/byte) plus it's additonal onboard-ports (3x UART, softSerial, SPI) as cheap and powerful multiplexer boards simultaneously with different additional i2c devices. Finally a Mega clone costs < 10 EUR. :mrgreen:

Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino

Posted: Sun Feb 07, 2016 8:22 pm
by danjperron
I would be able to hook up about 100 devices to 1 port, and UART I have only
Well you have RS-485 for that! Use modbus protocol.

I2C is not meant to be far away between devices.

What is your longest length between you devices!.

Rs-485 use the uart and it could be up to 1000 metres between the first and the last device.

Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino

Posted: Mon Feb 08, 2016 8:07 am
by tito-t
at danjperron: that's completely off-topic, didn't you read the topic question? it's about i2c as I have i2c devices to hook up.
at davenull:
great work! thank you very much! that did it! amazing that you found the bug (and that you were indeed the only one who found that!), I also never thought that sleep is different from delay using milliseconds, I was too much used to the Arduino wait command. Now that program is excellent, and I will probably first connect 1 Mega because of the AVR libs and it has almost the same pinout as the Due.
Also to all others, especially to Gordon for your first code you provided: Thank you very much for your support! Your first Rpi code was really a tremendous help!

Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino

Posted: Mon Feb 08, 2016 10:03 am
by davenull
hey,
I'm glad that it also works for you now!

Don't forget: with an Uno it SHOULD work as it is (the uno has no built-in i2c pullups),
but the Mega has 2 internal pullups to +5V.

...

OTOH, the Due has also built-in pullups, but they are to 3.3V. Although they cannot be disabled, they do not interfere with the data transfer to the Pi.
Alternatively, you may also use TWI1 on the Due, this one also has no pullups at all.

(I personally have not tried the Mega yet though, just the Due.)

Good luck! 8-)

Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino

Posted: Tue Feb 09, 2016 8:45 am
by davenull
update, important information!

I stand corrected for the Mega (information from Arduino Forum): It may perhaps damage the Raspi nevertheless !

The 50k are internal in the ATmega2560 chip and can be disabled.
The 10k are on the Arduino Mega 2560 board and can not be disabled. Perhaps you can try to scratch a pcb trace and work around that 10k.

The Arduino Mega 2560 is the only board with those 10k resistors on the board for I2C. Any other board would be no problem.

Connect 5V with 10k to 3.3V with 1k8. That makes 3.55V
I don't like that, often 3.6V is the limit for 3.3V chips, and this is very close.

Using a dirty trick with a resistor to GND to lower it might also cause trouble. The Arduino Mega board needs 3.5V to see a I2C level as high.

With a level shifter, the Arduino has to pull both sides of the level shifter down. A level shifter has often 10k on both sides.
Total current:
5V with 10k and 10k : 1mA
3.3V with 1k8 and 10k : 2.16mA
Together it is above 3mA, which is specified as the maximum current by the official I2C standard. But that 3mA is not very strict, it will work
http://gammon.com.au/forum/?id=10896&reply=5#reply5

My conclusion : Use a level shifter or an other Arduino board.
I'll stay then with the DUE for the moment.

Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino

Posted: Wed Feb 10, 2016 9:25 am
by davenull
update:

I tested 2 different levelshifters with a Mega, and in both cases the i2c line breaks after a couple of cycles - no i2c slave then detected by the raspi any more.
re-plugging a DUE instead: everything works fine again, for several hours continuously by no issues.

So I would assume now: the Mega most probably won't work, but with the DUE I'm fine.

Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino

Posted: Wed Feb 10, 2016 3:34 pm
by tito-t
hello, with my 3.3V Zero it also works from the start but there seem to be troubles with my Uno, it seems to block transmission.

Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino

Posted: Wed Feb 10, 2016 4:09 pm
by davenull
what the hell!
I have no Uno but heaving read this I tried my Nano (without level shifter):

Same Issue! Identical to Mega (with level shifter):

There is a short data transmission (sometimes 10, sometimes even less, sometimes up to 30) and then transmission blocks!
No Arduino slave found then anymore!
After reset its there again, but shortly after it's vanished again!

Code: Select all

pi@raspberrypi ~ $ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
This is my current code, sligthly improved for better error checking:

Code: Select all

//  Raspberry Pi Master code to send/receive byte arrays
//  to an Arduino as an I2C slave
// 
//  ver. 0.002a
 

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <wiringPi.h>
#include <wiringPiI2C.h>

#include <errno.h>
#include <string.h>

#define MSGSIZE 30


unsigned char  calcchecksum( unsigned char array[]) {   
  int32_t  sum=0;
  for(int i=2; i<MSGSIZE; ++i) sum+=(array[i]);
  return (sum & 0x00ff);
}



int main (void)
{
   
  int fd, i ;
  unsigned char test=0;
  unsigned char data [MSGSIZE] ;

  if ((fd = wiringPiI2CSetup (0x04) ) < 0)
  {
    fprintf (stderr, "Can't open RTC: %s\n", strerror (errno)) ;
    exit (EXIT_FAILURE) ;
  }


  for (;;)
  {
    memset(data, 0, sizeof(data) );
    data[0]=  0xff;    // init for transmission error check
    read (fd, data, MSGSIZE) ;
    if( data[1] != calcchecksum( data )  ) {
         // handle transmission error !
    }   
    else {
       printf ("  read:  ");
       for (i = 0 ; i < 7 ; ++i)
          printf ("  %3d", data [i]) ;
       //printf ("\n") ;
       delay(10) ;
     
       memset(data, 0, sizeof(data) );
       data[5]=  test++;
       data[0]=  0xff;
       data[MSGSIZE-1]= 0x04;
       data[1] = calcchecksum( data );
       
       write(fd, data, MSGSIZE) ;
       printf ("   write: ");
       for (i = 0 ; i < 7; ++i)
         printf ("  %3d", data [i]) ;
       printf ("\n\n") ;
       delay(10) ;     
    }
  }

  return 0 ;
}

Code: Select all

//  Arduino code to send/receive byte arrays
//  Arduino as an I2C slave
// 
//  ver. 0.002


#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(1);                                     // 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..
}

with the Due still everything works fine!

@Gordon, @joan, @all: can somebody help with this?

Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino

Posted: Thu Feb 11, 2016 6:24 pm
by davenull
no idea somebody?
not even Gordon and/or joan?

if pigpio should be able to support clock-stetching - how would the i2c code look like with pigpio?

Or instead, if possible: how to do it with wiringPi/wiringPiI2C?

Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino

Posted: Fri Feb 12, 2016 8:35 am
by tito-t
:( quite disappointing that no one else wants to help :(

Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino

Posted: Fri Feb 12, 2016 10:30 am
by gordon@drogon.net
tito-t wrote::( quite disappointing that no one else wants to help :(
Time. Energy. Day-Job.

-Gordon

Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino

Posted: Fri Feb 12, 2016 10:30 am
by gordon@drogon.net
davenull wrote:no idea somebody?
not even Gordon and/or joan?

if pigpio should be able to support clock-stetching - how would the i2c code look like with pigpio?

Or instead, if possible: how to do it with wiringPi/wiringPiI2C?
I don't think it's pigpio that supports it, but a newer version of the kernel driver.. So one day...

-Gordon

Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino

Posted: Fri Feb 12, 2016 11:13 am
by joan
gordon@drogon.net wrote:
davenull wrote:no idea somebody?
not even Gordon and/or joan?

if pigpio should be able to support clock-stetching - how would the i2c code look like with pigpio?

Or instead, if possible: how to do it with wiringPi/wiringPiI2C?
I don't think it's pigpio that supports it, but a newer version of the kernel driver.. So one day...

-Gordon
pigpio does support bit banged I2C on arbitrary GPIO. It does require a little bit of knowledge of low level I2C though. http://abyz.co.uk/rpi/pigpio/cif.html#bbI2CZip

Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino

Posted: Fri Feb 12, 2016 11:54 am
by davenull
oh, thank you, joan - but for my personal programming skills I must admit that this is far too sophisticated :(

Would you be so kind to provide a source code that would work out of the box, perhaps just a substitute to read(fd, data, MSGSIZE) and write(fd, data, MSGSIZE) ?

Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino

Posted: Fri Feb 12, 2016 12:44 pm
by gordon@drogon.net
joan wrote:
gordon@drogon.net wrote:
davenull wrote:no idea somebody?
not even Gordon and/or joan?

if pigpio should be able to support clock-stetching - how would the i2c code look like with pigpio?

Or instead, if possible: how to do it with wiringPi/wiringPiI2C?
I don't think it's pigpio that supports it, but a newer version of the kernel driver.. So one day...

-Gordon
pigpio does support bit banged I2C on arbitrary GPIO. It does require a little bit of knowledge of low level I2C though. http://abyz.co.uk/rpi/pigpio/cif.html#bbI2CZip
Ah, my mistake!
Some user-assembly required ;-)

-Gordon

Re: i2c code samples C/WiringPi: PCF8591, MCP23017, Arduino

Posted: Sat Feb 13, 2016 7:23 am
by davenull
thanks, now I slowly understand - admittedly late, but finally...

I assumed that something must be wrong in the source codes for Raspi or Arduino, although everything works fine with the codes
1) from either Arduino to either Arduino
2) from Raspberry Pi to Arduino DUE (+ Zero reported; both ARMs)
3) but NOT for Raspi to AVR Arduinos (Nano+Mega (+Uno reported) ).

Now it turned out that the reason for these transmission errors (mentioned in (3)) are located deep in the Raspberry Linux Kernel, and the cleanest + straightest way was to have a Kernel update which provides clock-stretching capabilities (CMIIW).
Hacking the Linux Kernel or the I2C protocol by something like bitbanging is no option to me personally (maybe to the OP, but I actually doubt that, too), so:
I stay with my Arduino Dues which work fine, I already use them
a) by UART and
b) eventually I can use them now by I2C and
c) I even can use AVR Arduinos like the Mega via UART (to Raspi plus a level shifter).

These are actually options enough to have IMO. Maybe some time in the future a Raspi Kernel update will provide even the last unfulfilled ability for AVR slaves to I2C.

To Tim: I would suggest you to take DUEs then too for your purposes, perhaphs additionally to your Zero (which I can't test cause I don't have a Zero, but hey....! ) :geek: