2

I created a module for an RTC. It looks like this:

local moduleName = ...
local M = {}
_G[moduleName] = M

---------- Local variables ---------------------
local id = 0
local address = 0x68


---------- Helper functions --------------------
local function bcdToDec(val)
    local hl=bit.rshift(val, 4)
    local hh=bit.band(val,0xf)
    local hr = string.format("%d%d", hl, hh)
  return string.format("%d%d", hl, hh)
end

local function decToBcd(val)
   local d = string.format("%d",tonumber(val / 10))
   local d1 = tonumber(d*10)
   local d2 = val - d1
   return tonumber(d*16+d2)
end

---------- Module functions --------------------
function M.Init(sda, scl)
    i2c.setup(id, sda, scl, i2c.SLOW)
end


function M.PrintTime()
    i2c.start(id)
    i2c.address(id, address, i2c.TRANSMITTER)
    i2c.write(id, 0x00)
    i2c.stop(id)
    i2c.start(id)
    i2c.address(id, address, i2c.RECEIVER)
    c=i2c.read(id, 7)
    i2c.stop(id)
    s = bcdToDec(string.byte(c,1))
    m = bcdToDec(string.byte(c,2))
    h = bcdToDec(string.byte(c,3))

    time=string.format(" %s:%s:%s", h, m, s)
    print(time);
end

function M.PrintDate()
    i2c.start(id)
    i2c.address(id, address, i2c.TRANSMITTER)
    i2c.write(id, 0x00)
    i2c.stop(id)
    i2c.start(id)
    i2c.address(id, address, i2c.RECEIVER)
    c=i2c.read(id, 7)
    i2c.stop(id)
    s = bcdToDec(string.byte(c,1))
    m = bcdToDec(string.byte(c,2))
    h = bcdToDec(string.byte(c,3))
    wkd = bcdToDec(string.byte(c,4))
    day = bcdToDec(string.byte(c,5))
    month = bcdToDec(string.byte(c,6))
    year = bcdToDec(string.byte(c,7))

    time=string.format(" %s.%s.%s", day, month, year)
    print(time);
end

return M

I saved this file as "ds3231_m.lua". Calling functions from another file works like this:

m = require 'ds3231_m'
m.Init(2,1)   --sda, scl = 2, 1
m.PrintTime()
--m.PrintDate()
package.loaded.ds3231_m = Nil

as well as

m = require 'ds3231_m'
m.Init(2,1)   --sda, scl = 2, 1
--m.PrintTime()
m.PrintDate()
package.loaded.ds3231_m = Nil

But when I try calling both functions:

m = require 'ds3231_m'
m.Init(2,1)   --sda, scl = 2, 1
m.PrintTime()
m.PrintDate()
package.loaded.ds3231_m = Nil

I get an error:

test.lua:4: attempt to call field 'PrintDate' (a nil value)

Can anyone tell me what is going wrong?

Thank you very much in advance!

Regards

1 Answer 1

4

Inside PrintTime (and PrintDate) you're doing m = something. That does overwrite your m from m = require(...). You should use locals in those functions:

function M.PrintTime()
    i2c.start(id)
    i2c.address(id, address, i2c.TRANSMITTER)
    i2c.write(id, 0x00)
    i2c.stop(id)
    i2c.start(id)
    i2c.address(id, address, i2c.RECEIVER)
    local c=i2c.read(id, 7)
    i2c.stop(id)
    local s = bcdToDec(string.byte(c,1))
    local m = bcdToDec(string.byte(c,2))
    local h = bcdToDec(string.byte(c,3))

    local time=string.format(" %s:%s:%s", h, m, s)
    print(time);
end

That way, you won't be editing any globals. Also do the same for PrintDate.

(If you did other_name_than_m = require(...) you wouldn't have noticed, but print(m) would still print a number, the amount of minutes from something)

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you very much, sometimes the solution is so simple :)
He could / should possibly also use local m = require 'ds3231_m'. Depends on what he needs though.
He probably should, but it doesn't really matter here. Inside a function, for temporary variables, you should use locals. What he does in his main script is up to him. (although locals are better in most cases)
@mfxfx1 If this answer helped you be sure to press the green checkmark to accept it! That helps future readers with similar problems to find answers just like you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.