perf
Posts: 3
Joined: Sat Jun 15, 2013 7:54 am

Can I2C be shared? It should!

Fri Jun 21, 2013 6:24 am

I have a problem with a Python daemon that uses I2C to write to a small 2x16 character LCD that is interfaced via an ATMEGA328P. The I2C bus is shared with a DS1307 RTC clock chip. The I2C bus is designed for sharing, but the Python daemon is aborted once every 12 hours with no traces in any logs.

I am using Raspbian “wheezy” - uname -a output below:
Linux lager 3.6.11+ #456 PREEMPT Mon May 20 17:42:15 BST 2013 armv6l GNU/Linux

Below is the code - just the essential portions - with comments - which demonstrates my problem.
Any help is welcomed.

Code: Select all

#!/usr/bin/python

import time
import select
import lageravr as avr # Home made Python extension in C.

'''
This code is taken from a Python daemon application which - for an unknown reason
gets a sudden abort, then aborted once every 12 hours thereafter. 

When idling, the application displays date and time on a 2 line times 16 character LCD, 
once each minute. 

This LCD is driven by an AVR microcontroller that is interfaced to the Pi by I2C-0 which is 
shared with an RTC chip. An level converter is used as the two external chips
are 5V devices. The software handling the I2c slave at the microcontroller is identical to the
Arduino twi.c code.

The I2C access is coded in C as a Python extension. The important piece of code is shown
below. Failure for file open failure are honored and the device file is closed immediately
after data written.

static int I2C_Open(int *file, unsigned char address)
{
    *file = (int)open(I2C_FILE_NAME, O_RDWR); 
    if(*file < 0) {
        return -1;
    } else {
        if(ioctl(*file, I2C_SLAVE, address) < 0) {
            return -1;
        }       
        return 0;
    }
}

static int SendToLCDLine1(char *text)
{
    int i2c_file, err,len;
    lcdbuf.cmd1 = 1;
    memset(lcdbuf.line1,' ',sizeof(lcdbuf.line1));
    strncpy(lcdbuf.line1,text,sizeof(lcdbuf.line1));
    err = I2C_Open(&i2c_file, 0x19);
    if (err == 0) {
        len = write(i2c_file,&lcdbuf.cmd1,sizeof(lcdbuf.line1)+1);
        close(i2c_file);
        return len;
    }
    return err;
}



'''

timeout = 30.0 # initially timeout.

while True:
    # inputfiles list is empty for this test. 
    # Nornally, strings from a barcode reader is handled.
    # but for this test this is removed.
    inputfiles = []
    r, w, e = select.select(inputfiles,[],[],timeout)
    
    # Nornally, strings from a barcode reader is handled here,
    # but for this test the code is removed.
        
    if not (r or w or e):
        # timeout
        nu = time.localtime()
        avr.writeLcdLine1(time.strftime('%a %d %b %Y',nu))
        avr.writeLcdLine2(time.strftime('Time is %H:%M',nu))
        
        epoc = time.time()
        # to is seconds left to next whole minute
        timeout = 60.0 - float(epoc%60)
        # Next timeout will occur at next minute rollover
        # The display time will appear accurate to the minute. 
    
    

User avatar
davef21370
Posts: 897
Joined: Fri Sep 21, 2012 4:13 pm
Location: Earth But Not Grounded

Re: Can I2C be shared? It should!

Fri Jun 21, 2013 1:11 pm

The code looks fine, have you tried the old fashioned method of printing something to the terminal after each function to see when it stops working? That way you can pin the problem down to the relevant bit of code.

Dave.
Apple say... Monkey do !!

Return to “Python”