Светодиодная матрица на MCP23017

forfrends
Offline
Зарегистрирован: 24.02.2015

Всем привет!

Решил я сделать светодиодную матрицу на MCP23017 и Arduino Pro Mini. Схема:

Код (тестовый):

#include <Wire.h>
#include "Adafruit_MCP23017.h"

Adafruit_MCP23017 mcp;

int i = 0;
byte A = 0;
byte B = 0;
uint16_t Data;

const byte bitmap[] PROGMEM = {
    //0x99,0x42,0x24,0x99,0x99,0x24,0x42,0x99  
    0x00,0x0E,0x06,0x0A,0x10,0x20,0x00,0x00                                        

};


void setup() {
    mcp.begin();      // use default address 0

    mcp.pinMode(0, OUTPUT);
    mcp.pinMode(1, OUTPUT);
    mcp.pinMode(2, OUTPUT);
    mcp.pinMode(3, OUTPUT);
    mcp.pinMode(4, OUTPUT);
    mcp.pinMode(5, OUTPUT);
    mcp.pinMode(6, OUTPUT);
    mcp.pinMode(7, OUTPUT);
    mcp.pinMode(8, OUTPUT);
    mcp.pinMode(9, OUTPUT);
    mcp.pinMode(10, OUTPUT);
    mcp.pinMode(11, OUTPUT);
    mcp.pinMode(12, OUTPUT);
    mcp.pinMode(13, OUTPUT);
    mcp.pinMode(14, OUTPUT);
    mcp.pinMode(15, OUTPUT);
}

void loop() {

    A = 1 << i;
    A=~A;
    B = pgm_read_byte(&bitmap[i]);

    Data = A << 8 | B;

    mcp.writeGPIOAB(Data);
    
    i++;
    if (i>7) i = 0;
    //delay(10);
}

Что должно  получиться:

А что получилось:

  

"Изображение" как-бы наплывает на пиксели, находящиеся справа. То есть в любом месте можно зажечь светодиод и справа от него так же будет светится еще один светодиод только на много тусклее. И чем выше частота обновления, тем выше яркость этих "двойников". Может кто знает с чем это может быть связано?

P.S. Может есть готовая библиотека для светодиодных матриц на MCP23017?

rkit
Offline
Зарегистрирован: 23.11.2016

паразитная емкость

b707
Offline
Зарегистрирован: 26.05.2017

на ошибки указывать можно или опять что-то доказывать начнете?

forfrends
Offline
Зарегистрирован: 24.02.2015

Разве я то-то доказывал? Вы перечитайте мой предыдущий пост. Я ничего не написал и именно за это меня начали поливать грязью. Есть ошибки - покажите, научите как правильно.

Я сделал предположение что обновление портов A и B MCP23017 делает не одновременно, а с небольшой задержкой. По этому реши сделать некоторое "обнуление" портов:

void loop() {
    A = 1 << i;
    A=~A;
    B = pgm_read_byte(&bitmap[i]);
    Data = A << 8 | B;

    mcp.writeGPIOAB(0b1111111100000000); 
    mcp.writeGPIOAB(Data);
    
    i++;
    if (i>7) i = 0;
    delay(1);
}

Лишние светодиоды перестали гореть, но частота обновления понизилась и яркость упала. Может есть какое-то другое решение данной проблемы?

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

rkit пишет:

паразитная емкость

В очередной раз сморозил глупость rkit

rkit
Offline
Зарегистрирован: 23.11.2016

жду опровержения

svm
Offline
Зарегистрирован: 06.11.2016

rkit пишет:

жду опровержения

При таких частотах, паразитная емкость никакой роли не сыграет. Здесь скорее всего косяк библиотеки. Возможно если обновлять данные, только при их изменении-эффект паразитной засветки исчезнет.

rkit
Offline
Зарегистрирован: 23.11.2016

При каких частотах? Много ты сам делал динамических индикаторов на светодиодах, можно поинтересоваться? А в почему бы не заглянуть в код библиотеки вместо "скорее всего"? Вот я заглянул.

b707
Offline
Зарегистрирован: 26.05.2017

svm пишет:

Возможно если обновлять данные, только при их изменении-эффект паразитной засветки исчезнет.

эти данные невозможно обновлять только при изменении - тут динамическая индикация

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

forfrends пишет:

 

Я сделал предположение что обновление портов A и B MCP23017 делает не одновременно, а с небольшой задержкой. По этому реши сделать некоторое "обнуление" портов:

Лишние светодиоды перестали гореть, но частота обновления понизилась и яркость упала. Может есть какое-то другое решение данной проблемы?

Да сначала пишется в порт А, потом в В. 

Что можно сделать:

- Поднять частоту I2C
- Взять другую библиотеку которая позволяет писать только в один порт. И "об'единичивать" только порт B
- Поменять на MCP23S17 . По SPI можно в несколько раз быстрее данные передавать

b707
Offline
Зарегистрирован: 26.05.2017

asam пишет:

- Взять другую библиотеку которая позволяет писать только в один порт. И "об'единичивать" только порт B

в библиотеке есть возможность включать-выключать отдельные пины. но быстрее не будет

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

b707 пишет:

asam пишет:

- Взять другую библиотеку которая позволяет писать только в один порт. И "об'единичивать" только порт B

в библиотеке есть возможность включать-выключать отдельные пины. но быстрее не будет

Причем здесь пины? Я говорил о порте целиком.

b707
Offline
Зарегистрирован: 26.05.2017

asam пишет:

Причем здесь пины? Я говорил о порте целиком.

при том, что задача ТС на каждом цикле выключить один пин и включить другой, что можно было бы делать по пинам... если бы включение одного пина не занимала больше времени, чем включение порта :)

Гриша
Offline
Зарегистрирован: 27.04.2014

не уверен, но ради эксперимента 

перед обновлением данных гасите все выходы т.е. сперва отправьте "0" данные, и следом сразу требуемые, после отправки небольшую задержку delayMicroseconds (). 

очень похоже на смещение, связанное с переходными процессами. т.к. переключение портов (вывод данных) не идеальный. т.е. порты отключаются не одновременно и не мгновенно. 

UPD блин, в посте 3 это уже испытали... скорее всего вы правы, только задержку не на delay а delayMicroseconds нужно делать. 

есть еще вариант - перевернуть матрицу т.е. диоды в ней  

Гриша
Offline
Зарегистрирован: 27.04.2014

а где у вас прерывания портов висят???? в воздухе? поработайте с прерываниями 100% с ними вопрос нужно решать, тогда без бесполезной посылки можно будет обойтись. 

forfrends
Offline
Зарегистрирован: 24.02.2015

Я с динамической индикацией раньше не имел дела. Я вообще не знал что то что я делаю называется динамической индикацией... По сути я начал создавать велосипед... Почитал кое-то на эту тему. Оказалось что описываемая мной проблема является обычным явлением для динамической индикации. Решается путем гашения всех сегментов перед тем как отобразить следующие.

Посмотрел библиотеку. Судя по коду, запись одного пина происходит никак не быстрее чем всего порта. 

b707
Offline
Зарегистрирован: 26.05.2017

Гриша пишет:

а где у вас прерывания портов висят???? в воздухе? поработайте с прерываниями 100% с ними вопрос нужно решать, тогда без бесполезной посылки можно будет обойтись. 

Гриша, вот убей - не вижу где вы там прерывания нашли. Покажите слепому

Гриша
Offline
Зарегистрирован: 27.04.2014

b707 пишет:

Гриша, вот убей - не вижу где вы там прерывания нашли. Покажите слепому

признаю... косяк, они несколько иначе работают... 

INTB - Interrupt output for PORTB. Can be configured as active-high, active-low or open-drain

 

ИМХО. все таки неудачная микросхема для этой задачи... продолжать эксперименты дальше думаю не стоит... это я к ТС обращаюсь, или ?

 

forfrends
Offline
Зарегистрирован: 24.02.2015

Как говорится - первый блин комом. Сама микросхема хорошая, ее можно использовать для динамической индикации, но подключать нужно по SPI, тогда скорость передачи данных будет до 10 MHz, (а значить и меньше задержки на переключение портов). На I2C поддерживаемые скорости: 100kHz, 400kHz, и 1.7MHz. На ардуино возможна скорость на 400kHz, но для динамической индикации это маловато. Так или иначе, я поднял частоту I2C  до 400kHz, это улучшило качество отображения (меньше задержки на обновление). Дальше никак - только переводить на SPI, но увы, не могу это сделать, так как печатная плата уже на руках, придется иметь дело с тем что есть.

Уже немного поекспериментировал с анимацией. В целом все не плохо! Всем спасибо за помощь!

SLKH
Offline
Зарегистрирован: 17.08.2015

forfrends пишет:

микросхема хорошая, ее можно использовать для динамической индикации,

мазохизм.

Гриша
Offline
Зарегистрирован: 27.04.2014

тогда возьмите пару SAA1064 тоже отличная микросхема...

ЭЙ, товарищи!!!!! кому какая отличная микросхема нравится? Давайте задачу решать только на любимых микросхемах?!!!! конечно, если она хоть немного подходит для решения....

ГЫЫЫЫЫЫЫ

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

forfrends пишет:

 На ардуино возможна скорость на 400kHz, но для динамической индикации это маловато. Так или иначе, я поднял частоту I2C  до 400kHz, это улучшило качество отображения (меньше задержки на обновление). Дальше никак - только переводить на SPI, 

Насколько я помню на Атмегах I2C разгоняется где-то до 700КГц

forfrends
Offline
Зарегистрирован: 24.02.2015

SAA1064, если не ошибаюсь, предназначена только для индикации 4-х семисегментных индикатора.

Гриша
Offline
Зарегистрирован: 27.04.2014

forfrends пишет:

SAA1064, если не ошибаюсь, предназначена только для индикации 4-х семисегментных индикатора.

верно, так я и предложил взять пару.

собственно я имел ввиду, что для таких целей MAX7219 (матрица 8х8) намного удобнее, ну хотя бы взять тетрис