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 ;
}
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..
}
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 ;
}
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..
}
Well you have RS-485 for that! Use modbus protocol.I would be able to hook up about 100 devices to 1 port, and UART I have only
I'll stay then with the DUE for the moment.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.
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: -- -- -- -- -- -- -- --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..
}
Time. Energy. Day-Job.tito-t wrote:quite disappointing that no one else wants to help
I don't think it's pigpio that supports it, but a newer version of the kernel driver.. So one day...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?
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#bbI2CZipgordon@drogon.net wrote:I don't think it's pigpio that supports it, but a newer version of the kernel driver.. So one day...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?
-Gordon
Ah, my mistake!joan wrote: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#bbI2CZipgordon@drogon.net wrote:I don't think it's pigpio that supports it, but a newer version of the kernel driver.. So one day...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?
-Gordon