Pyboard as i2c slave won't work

The official pyboard running MicroPython.
This is the reference design and main target board for MicroPython.
You can buy one at the store.
Target audience: Users with a pyboard.
unruhseth
Posts: 3
Joined: Sun Sep 30, 2018 1:56 am

Pyboard as i2c slave won't work

Post by unruhseth » Sun Sep 30, 2018 2:34 am

Hi there, I'm fairly new to the programming thing so don't understand stuff very good. The master is a raspberry pi and the pyboard is the slave and the raspberry pi is not picking up anything on the bus.

My code :

from pyb import I2C
I2c = I2C(1)
i2c. init(I2c. Slave, add = 0x40)

Maybe I'm missing a step somewhere?

jickster
Posts: 629
Joined: Thu Sep 07, 2017 8:57 pm

Re: Pyboard as i2c slave won't work

Post by jickster » Sun Sep 30, 2018 5:25 pm

Is that your entire code? You have to call receive or send.


Sent from my iPhone using Tapatalk Pro

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Pyboard as i2c slave won't work

Post by pythoncoder » Mon Oct 01, 2018 6:41 am

I think he's saying that the Pyboard doesn't respond to a bus scan. Perhaps someone who's used slave mode successfully will comment.
Peter Hinch
Index to my micropython libraries.

User avatar
Roberthh
Posts: 3668
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Pyboard as i2c slave won't work

Post by Roberthh » Mon Oct 01, 2018 11:32 am

I't might be just typos in the post, but shouldn'r it read:

Code: Select all

from pyb import I2C
i2c = I2C(1)
i2c. init(i2c.SLAVE, addr = 0x40)

unruhseth
Posts: 3
Joined: Sun Sep 30, 2018 1:56 am

Re: Pyboard as i2c slave won't work

Post by unruhseth » Mon Oct 01, 2018 3:28 pm

Yes that was typo. I just double checked and I have SLAVE in the code.

rhubarbdog
Posts: 168
Joined: Tue Nov 07, 2017 11:45 pm

Re: Pyboard as i2c slave won't work

Post by rhubarbdog » Tue Oct 02, 2018 6:06 am

your pyboard isn't doing any i2c comms for the i2cdetect to react with.
try this.

Code: Select all

import pyb

i2c = pyb.I2C(1)
i2c.init(pyb.I2C.SLAVE, addr = 0x40)

switch = pyb.Switch()

data = bytearray(200)
while not switch.value():
    try:
        data = i2c.recv(200)
    except OSError:
        data = None

    if data is None:
        print("None", end='    \r')
    else:
        print("0x%02x" % int(data[0]), end='    \r')

    pyb.delay(1000)

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Pyboard as i2c slave won't work

Post by pythoncoder » Tue Oct 02, 2018 10:37 am

@rhubarbdog In order for the slave to respond to a bus scan, is it necessary for the slave to be regularly attempting a read?
Peter Hinch
Index to my micropython libraries.

rhubarbdog
Posts: 168
Joined: Tue Nov 07, 2017 11:45 pm

Re: Pyboard as i2c slave won't work

Post by rhubarbdog » Tue Oct 02, 2018 10:51 am

I'm not sure. The i2c.recv times out with an OSError.
But in the first examples given i thought all that is missing is

Code: Select all

while True:
    pass
But needed to add an i2c.recv

SpotlightKid
Posts: 463
Joined: Wed Apr 08, 2015 5:19 am

Re: Pyboard as i2c slave won't work

Post by SpotlightKid » Tue Oct 02, 2018 2:35 pm

Yes, the client needs to do a recv() regularly, otherwise it can't respond to a scan(). The scan is performed by the master by sending each possible slave address to the bus and the client needs to respond with an ACK (i.e. pulling SDA low) when it recognizes his address. Note that the client recv() will throw an OSError with errno=5 (EIO) when the scan occurs (presumably because no data follows).

Here is an example of a full I2C interaction between two pyboards:

I2C slave code (start this first):

Code: Select all

from pyb import I2C

SLAVE_ADDRESS = 0x42
BAUDRATE = 100000

i2c_slave = I2C(1, I2C.SLAVE, addr=SLAVE_ADDRESS, baudrate=BAUDRATE)

while True:
    try:
        data = i2c_slave.recv(4)
    except OSError as exc:
        if exc.args[0] not in (5, 110):
            # 5 == EIO, occurs when master does a I2C bus scan
            # 110 == ETIMEDOUT
            print(exc)
    except KeyboardInterrupt:
        break
    else:
        print("RECV: %r" % data)
I2C master code:

Code: Select all

import time
from pyb import I2C

SLAVE_ADDRESS = 0x42
BAUDRATE = 100000

i2c_master = I2C(1, I2C.MASTER, baudrate=BAUDRATE)
i2c_master.scan()

for i in range(10):
    i2c_master.send(b"%04i" % i, addr=SLAVE_ADDRESS)
    time.sleep(0.5)
Terminal output of master:

Code: Select all

[66, 80, 81, 82, 83]
(Obviously, there are other, internal I2C slaves connected to I2C bus 1.)

Terminal output of the slave:

Code: Select all

RECV: b'0000'
RECV: b'0001'
RECV: b'0002'
RECV: b'0003'
RECV: b'0004'
RECV: b'0005'
RECV: b'0006'
RECV: b'0007'
RECV: b'0008'
RECV: b'0009'

OutoftheBOTS_
Posts: 847
Joined: Mon Nov 20, 2017 10:18 am

Re: Pyboard as i2c slave won't work

Post by OutoftheBOTS_ » Wed Oct 03, 2018 2:52 am

This what I found when using I2C Slave mode on the STM32 port of MP. The Slave has to be constantly monitoring for data from the master or the master will receive a NACK. This sort of made it not useful, as the slave device can't really go off and do things or the master will get a NACK back.

Just recently Laboris updated his I2C SLAVE on his port and it works on an interrupt. U can either setup an array that acts like a register that the master can read/write too or you can set it up that on any calls from the master it will execute a call back function. This made the SLAVE mode useful as you can have the slave device off doing tasks and the master can interrupt it when needed and the Master won't receive a NACK.

Post Reply