• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Нужна помощь Работа с TM1637

VelAndr

New member
Приветствую уважаемое сообщество!
Не могу заставить нормально работать модуль 4-разрядного 7-сегментного индикатора на TM1637.
Там по даташиту - практически I2C, только немного странный. На просторах интернета кому-то удавалось использовать I2C так, как у меня в прилагаемом коде, а библиотека для ардуины дрыгает ногами напрямую (и у нее это явно лучше получается)
Код:
i2c.setup(0,6,7,i2c.SLOW)

i2c.start(0)
i2c.write(0,64)
i2c.stop(0)

i2c.start(0)
i2c.write(0,192,156,122,158,2,4,142)
i2c.stop(0)

i2c.start(0)
i2c.write(0,136,7)
i2c.stop(0)
Интересно, что если я запускаю i2cscan, то какие-то цифры на индикаторах моргают, и даже в процессе экспериментов один раз модуль заработал (!!!), правда не совсем по даташиту, но распиновку индикаторов по ногам микросхемы я сделал. Но после перезагрузки модуля все снова перестало работать.
Подскажите пожалуйста, кому удалось завести модуль, что не так, и поделитесь рабочим куском скрипта, если можно!
P.S. Не очень хочется копировать ардуиновскую либу под nodemcu и дрыгать ногами ибо будет медленно и накладно.
Спасибо!
 

VelAndr

New member
А есть пример хоть какой-нить?
Там судя по даташиту вполне себе подобие i2c.
 

NutsXXXL

New member
@VelAndr посмотрел еще - теперь вижу _домодифицированный_ spi - 9ый бит в клоках. такое действительно проще вручную побитно, либо 8 bit по spi а 9ый бит софтом догенерировать..
у i2с есть еще заголовочный байт адреса+напрявления данных, плюс там манипуляции с подтянутыми и неподтянутыми состояния выводов.
 

VelAndr

New member
@NutsXXXL Но ведь кому-то удавалось запустить модуль через i2c! И у меня он один раз нормально отвечал на команды практически по даташиту (как я его до этого довел - отдельная тема, но работало ведь!). Понятно, что там, вместо единого адреса для общения с мс, есть набор команд (тех же, в принципе, адресов).
И странно, что и на форуме .com тоже никто до меня с этим китайским поделием с nodemcu не работал.
Чую, придется расчехлять старый комп с win7 и логический анализатор (на win10 драйвера не встали). Буду искать отличия с даташитом. Ведь у других-то на других микроконтроллерах вроде срабатывало...
Спасибо! Под анализатором мож и spi посмотрю (да этого плотно с ним не работал, и настроек, тем более в nodemcu, не знаю)
 

NutsXXXL

New member
@VelAndr i2c на esp позволяет сгенерировать даже видеосигнал. но думаю что тут не стандартные библиотечные функции нужны..
 

Gooman

New member
Не получилось ли наладить работу с этим дисплеем? Вот есть на lua чей-то код, но у меня не работает (ничего не выводится, без ошибок).
 
Последнее редактирование:

Gooman

New member
Мофицировал версию из репозитория git: GitHub - uaraven/tm1637-esp: Module for controlling 4 digit numerical display based on TM1637 driver for NodeMcu lua on ESP8266
Убрал бесконечный цикл в функции i2c_ack (), заменил задержкой. Поверено - работает.
Для работы требуются модули в прошивке: gpio, bit.
Код из сообщения нужно вставить в файл с названием filename.lua (название файла задайте свое).
Использование:
Код:
dofile("filename.lua").init(clk, dio) -- инициализация, передать номера контактов clk и dio
dofile("filename.lua").clear() -- очистка
dofile("filename.lua").setBr(x) -- установка яркости (x = [0..7])
dofile("filename.lua").writeS('1234') -- вывод строки на экран
dofile("filename.lua").writeS('1.234') -- по идее, должно зажечь точку возле цифры 1, однако у меня зажигается двоеточие.
Вроде, яркость надо устанавливать до первого вывода. Иначе экран будет выключенным. При последующем выводе яркость можно менять уже только по необходимости.
Впоследствии постараюсь доработать код для вывода тире (минуса).
Я не являюсь автором первоначального кода.

Nodemcu ESP8266 Lua Tm1637 script:
Код:
---
-- @description Driver for 4-digit 7-segment displays controlled by TM1637 chip
-- @date September 08, 2016
-- @author ovoronin
---
--------------------------------------------------------------------------------

local M
do
    I2C_COMM1 = 0x40
    I2C_COMM2 = 0xC0
    I2C_COMM3 = 0x80

    cmd_power_on = 0x88
    cmd_power_off = 0x80

    pin_clk = 7
    pin_dio = 3
    brightness = 0x0f
    power = cmd_power_on

    digits = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F}
    _dot = 0x80
    _dash = 0x40

    function clk_high()
      gpio.write(pin_clk, gpio.HIGH)
    end

    function clk_low()
      gpio.write(pin_clk, gpio.LOW)
    end

    function dio_high()
      gpio.write(pin_dio, gpio.HIGH)
    end

    function dio_low()
      gpio.write(pin_dio, gpio.LOW)
    end


    function i2c_start()
      clk_high()
      dio_high()
      tmr.delay(2)
      dio_low()
    end

    function i2c_ack ()
      clk_low()
      dio_high()
      tmr.delay(5)

      gpio.mode(pin_dio, gpio.INPUT)
      --while ( gpio.read(pin_dio) == gpio.HIGH) do
      --end
      tmr.delay(50)
      gpio.mode(pin_dio, gpio.OUTPUT)

      clk_high()
      tmr.delay(2)
      clk_low()
    end

    function i2c_stop()
      clk_low()
      tmr.delay(2)
      dio_low()
      tmr.delay(2)
      clk_high()
      tmr.delay(2)
      dio_high()
    end

    function i2c_write(b)
      for i = 0, 7, 1
      do
        clk_low()
        if bit.band(b, 1) == 1 then
          dio_high()
        else
          dio_low()
        end
        tmr.delay(3)
        b = bit.rshift(b, 1)
        clk_high()
        tmr.delay(3)
      end
    end

    function _clear()
     i2c_start()
        i2c_write(I2C_COMM2)
        i2c_ack()
        i2c_write(0)
        i2c_ack()
        i2c_write(0)
        i2c_ack();
        i2c_write(0)
        i2c_ack()
        i2c_write(0)
        i2c_ack()
      i2c_stop()
    end

    function init_display()
        i2c_start()
        i2c_write(I2C_COMM1)
        i2c_ack()
        i2c_stop()
        _clear()
        i2c_write(cmd_power_on + brightness)
    end

    function write_byte(b, pos)
        i2c_start()
        i2c_write(I2C_COMM2 + pos)
        i2c_ack()
        i2c_write(b)
        i2c_ack()
        i2c_stop()
    end

    function init(clk, dio)
        pin_clk = clk
        pin_dio = dio

        gpio.mode(pin_dio, gpio.OUTPUT)
        gpio.mode(pin_clk, gpio.OUTPUT)

        init_display()
    end

    function set_brightness(b)
      if b > 7 then b = 7 end
      brightness = bit.band(b, 7)

      i2c_start()
      i2c_write( power + brightness )
      i2c_ack()
      i2c_stop()
    end

    function write_string(str)
      local pos = 3
      local i = #str
      local dot
      while (i >= 1) do
        local s = str:sub(i,i)
        if s == '.' then
          dot = true
          i = i - 1
          s = str:sub(i,i)
        else
          dot = false
        end
        local digit = tonumber(s)
        local bt = digits[digit+1]
        if dot then bt = bt + _dot end
        write_byte(bt, pos)
        pos = pos - 1
        i = i - 1
      end
    end

    function clear()
      _clear()
    end

    M = {
        clear = clear,
        init = init,
        writeS = write_string,
        setBr = set_brightness,
    }
end
return M
 
Последнее редактирование:

ander

New member
Приветствую уважаемое сообщество!
Не могу заставить нормально работать модуль 4-разрядного 7-сегментного индикатора на TM1637.
Там по даташиту - практически I2C, только немного странный. На просторах интернета кому-то удавалось использовать I2C так, как у меня в прилагаемом коде, а библиотека для ардуины дрыгает ногами напрямую (и у нее это явно лучше получается)
Код:
i2c.setup(0,6,7,i2c.SLOW)

i2c.start(0)
i2c.write(0,64)
i2c.stop(0)

i2c.start(0)
i2c.write(0,192,156,122,158,2,4,142)
i2c.stop(0)

i2c.start(0)
i2c.write(0,136,7)
i2c.stop(0)
Интересно, что если я запускаю i2cscan, то какие-то цифры на индикаторах моргают, и даже в процессе экспериментов один раз модуль заработал (!!!), правда не совсем по даташиту, но распиновку индикаторов по ногам микросхемы я сделал. Но после перезагрузки модуля все снова перестало работать.
Подскажите пожалуйста, кому удалось завести модуль, что не так, и поделитесь рабочим куском скрипта, если можно!
P.S. Не очень хочется копировать ардуиновскую либу под nodemcu и дрыгать ногами ибо будет медленно и накладно.
Спасибо!
Наверно, несколько поздновато, но лучше уж поздно, чем никогда.
Не знаю уж, виноват тут не совсем i2c tm1637, или в nodemcu так i2c реализована, но часть данных нужно отправлять другим концом. То есть i2c.write(0, 0x40) не сработает как команда записи в регистры, отправлять нужно 0x02 (прочитайте бинарное представление справа налево!)
Например, такой код у меня работает:
Код:
i2c.start(0)
i2c.write(0,0x02)
i2c.stop(0)
i2c.start(0)
i2c.write(0,0x03,0xee,0x3f,0x9c,0x7a)
i2c.stop(0)
i2c.start(0)
i2c.write(0,0x51)
i2c.stop(0)
и выводит "Ab:Cd"
Обратите внимание, команды и адрес записи развернуты:
0x02 - это 01000000 из даташита
0x03 - это 11000000, адрес регистра c0H из того же даташита
0x51 - 10001010 - включили дисплей, яркость 4/16
А вот данные по сегментам не развернуты, например, "1" будет 01100000 - 0x60
 
Сверху Снизу