-->
Page 1 of 4

I2C scanner - my first lua program

PostPosted: Sun Dec 28, 2014 5:22 pm
by gwizz
<edit> there is an improved version of script below</edit>

Hey!

Inspired by the great work going on here - and especially delighted that Zeroday has opened up the lua firmware - I decided to try writing a program in lua.

I needed to start working with i2c so I decided to port a scanner sketch over - see here for an arduino(ish) example: http://jeelabs.net/boards/6/topics/4356

So after a bit of head-scratching here it is (any improvements, suggestions etc welcomed!):
Code: Select all-- Based on work by zeroday & sancho among many other open source authors
-- This code is public domain, attribution to gareth@l0l.org.uk appreciated.

id=0  -- need this to identify (software) IC2 bus?
sda=3 -- connect to pin GPIO0
scl=4 -- connect to pin GPIO2

-- initialize i2c with our id and pins in slow mode :-)
i2c.setup(id,sda,scl,i2c.SLOW)

-- user defined function: read from reg_addr content of dev_addr
function read_reg(dev_addr, reg_addr)
     i2c.start(id)
     i2c.address(id, dev_addr ,i2c.TRANSMITTER)
     i2c.write(id,reg_addr)
     i2c.stop(id)
     i2c.start(id)
     i2c.address(id, dev_addr,i2c.RECEIVER)
     c=i2c.read(id,1)
     i2c.stop(id)
     return c
end

print("Scanning I2C Bus")
for i=0,127 do
     if (string.byte(read_reg(i, 0))==0) then
     print("Device found at address "..string.format("%02X",i))
     end
end


I am really starting to enjoy lua - it seems really easy to just do stuff!

Keep up the good work everybody :D

2015 is gonna be a great year for IoT gadgets!!!

G

Re: I2C scanner - my first lua program

PostPosted: Tue Dec 30, 2014 11:50 am
by sancho
Nice program.
However, I have multiple devices, that would not work with this - e.g. my MCP23017 responded with 0xFF (all outputs) for register address 0x00 - in other words, the script of yours would not detect it. The same applies to my i2c light intensity sensor and various other devices.
However, since the documentation update, device discovery on i2c bus is quite simple - just verify the ACK packet after address byte is sent.
Like I did in my example here.

Re: I2C scanner - my first lua program

PostPosted: Sat Jan 03, 2015 3:43 pm
by gwizz
D'oh!

Can't believe I missed your version, which achieved what I really wanted to do but sort of fluffed!!

Thanks for the feedback, really appreciate it.

Off to try to get my pH circuit (based on MCP3221) to work.

Improved I2C scanner - now with Automagic wiring!

PostPosted: Sat Jan 03, 2015 5:17 pm
by gwizz
OK - I had a brainwave and decided to implement an autowiring function for the i2c scanner.

Thanks to sandos I got the device test function working properly.

Now you can attach SCL and SDA to any GPIO pins that are legal - that is, GPIO 0, 2, 4, 5, 12, 13 or 14.

The program should scan through all possible combinations of wiring to find your i2c device. The scan takes approx 3 seconds for me.

Code: Select all-- Based on work by sancho and zeroday among many other open source authors
-- This code is public domain, attribution to gareth@l0l.org.uk appreciated.

id=0  -- need this to identify (software) IC2 bus?
gpio_pin= {5,4,0,2,14,12,13} -- this array maps internal IO references to GPIO numbers

-- user defined function: see if device responds with ACK to i2c start
function find_dev(i2c_id, dev_addr)
     i2c.start(i2c_id)
     c=i2c.address(i2c_id, dev_addr ,i2c.TRANSMITTER)
     i2c.stop(i2c_id)
     return c
end

print("Scanning all pins for I2C Bus device")
for scl=1,7 do
     for sda=1,7 do
          tmr.wdclr() -- call this to pat the (watch)dog!
          if sda~=scl then -- if the pins are the same then skip this round
               i2c.setup(id,sda,scl,i2c.SLOW) -- initialize i2c with our id and current pins in slow mode :-)
               for i=0,127 do -- TODO - skip invalid addresses
                    if find_dev(id, i)==true then
                    print("Device found at address 0x"..string.format("%02X",i))
                    print("Device is wired: SDA to GPIO"..gpio_pin[sda].." - IO index "..sda)
                    print("Device is wired: SCL to GPIO"..gpio_pin[scl].." - IO index "..scl)
                    end
               end
          end
     end
end


It results in this sort of output:
Code: Select all> dofile("i2c_scan.lua")
Scanning all pins for I2C Bus device
Device found at address 0x4C
Device is wired: SDA to GPIO14 - IO index 5
Device is wired: SCL to GPIO2 - IO index 4


Please do give feedback - if this has been useful for you or if you can help me improve my lua skills!!

Happy hacking :D