Комментарии 47

Полезная статья. Несколько раз мне пригодился бы такой подход.
Автор конечно мастер скриншотов :)

НЛО прилетело и опубликовало эту надпись здесь
Если два провода уже проложены, а третий проложить возможности нет.
Милый Kunststück.
Может — даже полезный, если рассматривать с т.з. того, что не надо засирать радиодиапазон для такого низкоскоростного устройства.
вместо ардуины можно было 595 сдвиговым регистром и парой RC цепочек обойтись.
А куда тогда девать ардуину? Она должна быть… везде, даже в генераторе меандра простейшем (555 юзают только деды и не продвинутые).
На самом деле — китайцам положена какая-нибудь премия вроде той что дали Курниковой за «вклад в развитие высокоскоростного интернета». «Левые» тиражи любого заказанного устройства привели к замене всего чего можно микропроцессорами…
Вот вы смеётесь с ардуины, а у меня акумы для шуруповерта с Bluetooth…
Это интересное решение. Даже придраться особо не к чему. Взял на заметку и повторю.
Что изменю у себя:
1. Инициализацию дисплея полностью перенесу на видео-мк.
2. Вместо ардуино, поставлю 20-ти ногую stm32f042/f030
2. В схеме, вместо n-mosfet AO3400A, поставлю биполярник BCR512
Если результат будет, я даже готов купить с десяток таких корвертеров.
Без подсветки 1602 потребляет около 3 ма. Лет 20 назад питал по аналогии с 1-wire. На выходе мастера был только резистор подтяжки на 470 ом, без всего этого огорода. Притом что к мастеру планировалось подключить 1602 в кол-ве 16 штук.
Схема — трэш и угар. Почему все ардуинщики не могут нарисовать схему, чтобы было понятно нормальным людям?
А что не так со схемой??? Ну кроме того что там на входе нет токоограничивающего резистора и резистора подтяжки (которые, кстати говоря, при определенных условиях, не обязательны)???
И нормальные люди — это кто?? Те кому надо все разжевать и в рот положить или те кто все же способен самостоятельно добыть недостающие знания или синтезировать их самостоятельно???
Аааааа. Дак вы об этом убожестве… Тут с вами не поспоришь. Но все же и тут при желании можно разобраться.
А статью зачем читать?
самостоятельно добыть недостающие знания или синтезировать их самостоятельно
я и так могу. Зачем мне бесполезная картинка?
Идея очень интересная в плане практического применения.

коммутировать ему приходится всего 200 мА.
Ардуино потребляет 17 ма и подсветка 40 мА (максимальный ток выхода). Как получилось 200 мА?

Хотел бы обратить внимание что примененный модуль ЖКИ у Вас новый, с яркими диодами подсветки. Это видно по выступающему справа от экрана блестящему кожуху. На обычных (старых) модулях ток подсветки примерно 160 мА (от 5В). При их использовании выход желательно бы усилить транзистором.
У меня попадались 1602 с алишки, которые жрали до 1А легко с подсветкой на полную мощность.
1А 5В это 5 ватт мощности на светодиоде. Это же прожектор-фонарик!.. Может, китайцы не поставили токоограничивающий резистор?
Вот жесть то, еще адруинку запихать… Если уже так хочется передать данные по двум проводам хоть на километр, то меняйте полярность, модулируя переменку хоть фазой, хоть частотой.
По буду занудой… На километре эти 5В упадут настолько, что работать не будет. 5В и 1А на километр — это надо ВВГ 2.5 мм2 или что-то на уровне, а не китайские говно-провода с сечением 0.1 мм2 :))

P.S. просто случай из жизни, одни ардуинщики знакомые пытались запитать цепочку устройств от 12В. Первые 20 устройств работали, а потом что-то переставали. Суммарное потребление было 12В и пара ампер, через километр было уже 5...6В, провод какой-то китайский с алишки около 0.5 мм2.
Помню, я лично пытался питать роутер от его родного БП (12В переменки, в роутере — выпрямитель и линейный стабилизатор) по неиспользуемым парам UTP. Метров 70 что-ли… Не получилось…
У меня возникает только один вопрос — зачем там процессор?
Прекрасно это все реализуется одной примитивной микрухой 74hc595. более того я так делал и оно работает!

схема проверенная в железе.


image

Вот обновленная картинка
image

Именно так данные и латч — через КС цепочки + диоды для возможности положительные полуволны пролетать 1 тактом. в общем случае на атмеге 8 мегагерц получается 4 таких экрана перерисовывать 10 раз в секунду без визуальных глюков. кондеры в релизе одинаковые — отличаются в 10 раз резисторы. Нога порта атмеги легко вытягивает питание и передачу данных и даже подсветку трем экранам. без подсветки максимум что пробовал — 10 экранов — работает стабильно.
Нога порта атмеги легко вытягивает питание и передачу данных и даже подсветку трем экранам.
На все экраны выводится одинаковая информация?
Сдвиговые регистры можно включить цепочкой друг за другом, тогда будет разная.
Можно пример кода для полного понимания процесса?
Вообще давно интересуюсь однопроводными протоколами. Найти простое и надёжное решение в интернете не очень легко. Но вот человек предложил,- и сразу оказывается, что это все давно и так знали. Где они были, когда я искал? Я, кстати, пришёл к такому же варианту, что и в переведённой статье. Для него достаточно просто контроллера без обвязки, и места на плате меньше, чем любой другой вариант. Но неинтересно, так как слишком просто.
Код быдлячий — из первого проекта ProofOfConcept и потом был переделан на прерывания но не в этом суть. принцип работы остался тем же

код
void LcdWireOut(unsigned char a)
{
    unsigned char b=0;
    //unsigned char mask = 1;
    
    for(b=0;b<8;b++)
    {
        if(a&(0b00000001<<b))
        {
            OwDisp=1;
            delay_us(1);
            #asm("cli");
                OwDisp=0;
                //delay_us(1);
                #asm("nop");
                #asm("nop");
                #asm("nop");
                #asm("nop");
                OwDisp=1;
            #asm("sei");                        
        }            
        else
        {
            OwDisp=1;   
            OwDisp=0;
            delay_us(20);
            OwDisp=1;   
        }
        //mask=mask<<1;
    }
     
    delay_us(200);
    OwDisp=0;
}

void UpdLcdWire()
{
    unsigned char a=0;
    if(LCD_B0)
        a |= 1 << 7;
    
    if(LCD_BKL)
        a |= LCD_BKL << 6; 
        
    if(LCD_DB7)
        a |= LCD_DB7 << 5;
        
    if(LCD_DB6)
        a |= LCD_DB6 << 4;
        
    if(LCD_DB5)
        a |= LCD_DB5 << 3;
        
    if(LCD_DB4)
        a |= LCD_DB4 << 2;
        
    if(LCD_DE)
        a |= LCD_DE  << 1;
        
    if(LCD_RS)
        a |= LCD_RS;          
        
    LcdWireOut(a);    
}

void lcd_init(void)
{
    LCD_B0=0;
    LCD_BKL = 1;
    
    LCD_DE=0;
    LCD_RS=0;

    LCD_DB4=0;
    LCD_DB5=0;
    LCD_DB6=0;
    LCD_DB7=0;

    UpdLcdWire();

    delay_ms(50);//wait for LCD internal initialization

    lcd_init_write(0x30);
    lcd_init_write(0x30);
    lcd_init_write(0x30);
    lcd_init_write(0x20);//set 4-bit mode
    lcd_write_command(0x28);//4 bit mode, 2 strings
    lcd_write_command(0x04);//AC=decrement, S=no shift screen
    lcd_write_command(0x85);

    lcd_clear();
}

void lcd_init_write(char cmd)
{
    LCD_DE=0;
    LCD_RS=0;//command mode
    
    LCD_DB4=(cmd&16)>>4;
    LCD_DB5=(cmd&32)>>5;
    LCD_DB6=(cmd&64)>>6;
    LCD_DB7=(cmd&128)>>7;
    UpdLcdWire();

    LCD_DE=1;
    UpdLcdWire();

    LCD_DE=0;
    UpdLcdWire();
}

void lcd_write_command(char cmd)
{
    LCD_RS=0;//command mode
    lcd_send_data(cmd);
}

/// Send to data register ///
void lcd_write_data(char data)
{
    LCD_RS=1;//data mode
    lcd_send_data(data);
}

/// Send prepared data ///
void lcd_send_data(unsigned char dta)
{
    LCD_DE=0;
    
    LCD_DB4=(dta&16)>>4;//out higher nibble
    LCD_DB5=(dta&32)>>5;
    LCD_DB6=(dta&64)>>6;
    LCD_DB7=(dta&128)>>7;
    
    LCD_DE=1;//latch-up
    UpdLcdWire();

    LCD_DE=0;
    UpdLcdWire();

    LCD_DB4=(dta&1);//out lower nibble
    LCD_DB5=(dta&2)>>1;
    LCD_DB6=(dta&4)>>2;
    LCD_DB7=(dta&8)>>3;
    
    LCD_DE=1;
    UpdLcdWire();

    LCD_DE=0;
    UpdLcdWire();
}

void lcd_putchar(char chr)
{
    #ifdef WithoutXYControl
    if(chr<31)
        return;
    #else
    if((chr<31)||(lcd_x_cnt>=20))
        return;
    #endif     
        
    lcd_write_data(chr);

    #ifndef WithoutXYControl
    lcd_x_cnt+=1;
    #endif

}

void lcd_puts(char *str)
{
    char k;
    while (k=*str++) lcd_putchar(k);
}


Спасибо. Прояснилось не сильно, правда. Циклограммы бы глянуть, но это я уже много хочу.
все же просто!
функция UpdLcdWire собирает байт для отправки в линию — тут пример только на один сдвиговик/экран.
дальше функция LcdWireOut передает побитово 9 бит в шину.
изначально она выдает в линию 1-0-1 без задержек если в текущем передаваемом бите единица — так кондер на линии данных не успеет просесть до нуля и защелка захватит единицу на входе.
Если же бит был равен нулю то 1-0 делается почти без задержки а вот второй этам 0-1 делается с задержкой — тогда кондер на линии данных успеет разрядиться до порога ниже 2-х вольт и перепад 0-1 на тактовом входе — засосет в защелку нолик. и так далее 8 раз. линия вконце бита остается в единице так как перепад 1-0 на такте не создает процесса сдвига.
В то же время на второй защелке сдвиговыйРегистр-выход все время бОльшим конденсатором удерживается всегда единица так как за 20 микросекунд он не успеет сколь-либо значимо разрядиться а диод шоттки каждый раз при единице на выходе будет резко дозаряжать его до полного бака. и только в конце после всех 8-ми бит мы надолго — 200 миллисекунд опускаем линию в ноль тем самым разрядив до нуля кондер на LE и данные при поднятии 0-1 — захлопнутся со сдвиговой цепочки на выход.

ключевые моменты таковы:
1) задержка 0-1 при передаче нуля должна быть больше 15 микросек но не дольше 100 — для этого глушим прерывания на это время.
2) передача единицы — должна проходить с задержкой не более 5 микросек. в идеале без задержки но 4 nop туда вставлены так как шоттка не успевает зарядить кондер на линии входных данных ну и сопротивление выхода и так далее.
3) вконце нужно надолго погасить линию в ноль но вопервых паразитрное питание = кондер разрядится так что будет мигать подсветка, а во вторых кроме как экран перерисовывать у проца есть и другие дела потому 200 мсек просто как оптимальный минимум. Важно чтоб микруха на входе ST-CP почуяла переход 0-1.

Диоды нужны чтобы небыло проблем с длительной передачей одних нулей или единиц. без них после каждой передачи 4-х нулей пришлось бы на 100 микросекунд задержаться в единице чтоб восполнить потерю напруги на конденсаторе выходной защелки.

Как это все выглядит на осцилограмме?
А вот так
image

image

Собственно на осцилограмме видно 20 микросек 8 микросек и некоторая неоднородность т.к. иногда в процесс передачи вмешивается прерывание но оно не рушит передачу данных т.к. критически важные места защищены. впоследствии код переведен на прерывания по таймеру и двойную буферизацию и стало возможно подготавливать следующий снимок состояния ног пока собственно текущее состояние ещё передается + переписался драйвер управления экранами — вместо управления каждым экраном по очереди я тупо храню всё содержимое каждого из экранов в оперативке и когда надо экраны перерисовать — просто впаралель всем экранам передаю одну команду — курсор в начало первой строки — и выпаливаю подряд 1-2-3-4-5-6-7-8 символы каждому экрану впаралель — так сильно ускоряется массовое обновление но ценой оперативки на экранный буфер и скоростью изменения одной буквы неа одном экране — перерисовывается всеравно весь массив — впрочем это не недостаток — так вероятность остановки одного из экранов с ошибкой в передаче данных практически сводится к нулю или к малозаметрому проявлению на 50 мсек этой самой ошибки — следующее обновление всеравно перерисует все экраны.
Спасибо за исчерпывающий ответ! Вы не хотели бы оформить это в публикацию? Информация очень нужная, и найти её как комментарий нереально, а было бы это статьёй на Хабре… Даже в нынешнем виде информации больше, чем в статье, под которой коммент расположен.
По коду мне не всё понятно, у меня в Си мало опыта. Но сам принцип ясен, не сильно отличается от Управление семисегментными индикаторами по одному проводу или Управление по одному проводу.
ну в первом примере просто сдвиговик — во время сдвига оно глюки на экран показывает хотя если быстро и нечасто то не заметиш а второй случай — ну там доп триггер применен — тоже не очень… всяко два резика два кондера и один сдвоенный диод попроще будут и на выход только то что нужно выдают.
Прекрасно это все реализуется одной примитивной микрухой 74hc595. более того я так делал и оно работает!
точно два провода, вместе с питанием?
Да, питание от данных точно так же отделяется диодом с большой ёмкостью.
Клоки, данные и чипселект для защелкивания данных — разделяются двумя RC цепочками. Как на схеме из комментария выше (скорее всего), которую не видно.
Микруху эту еще заказать надо, а ардуина у многих валяется в ящике стола. Кроме того, на ардуину можно навесить дополнительных функций, например инициализацию, скроллинг символов.
к чему мелочиться, можно передавать закодированную информацию и ардуиной раскодировать на дисплей. можно еще много чего придумать чтоб оправдать оверкилл, но промышленное решение будет самое дешевое и надежное, с 595 микросхемой :)
Всё равно будет какой-то свой протокол поверх этого однопроводного интерфейса, что ничем особо не отличается от какого-нибудь кривого (посылать в УАРТ байт для передачи одного бита) управления сдвиговым регистром по одному проводу импульсами разной длительности.
А «разгружать» основной процессор поставив дополнительную ардуину в качестве «видеокарты» для 16х2 — так себе идея.
Только если надо здесь и сейчас что-то соорудить из того что есть под рукой, приходилось как-то заменять пару микросхем медленной, обычной 74 логики микроконтроллером, в качестве временного патча.
Вот обновленная картинка
image

Именно так данные и латч — через КС цепочки + диоды для возможности положительные полуволны пролетать 1 тактом. в общем случае на атмеге 8 мегагерц получается 4 таких экрана перерисовывать 10 раз в секунду без визуальных глюков. кондеры в релизе одинаковые — отличаются в 10 раз резисторы. Нога порта атмеги легко вытягивает питание и передачу данных и даже подсветку трем экранам. без подсветки максимум что пробовал — 10 экранов — работает стабильно.
два… три то если надо много то перемычка разрывается и питание дается отдельно. или когда подсветке надо больше газу :) изначально два
С ардуинкой? Надпись «Data overkill» смотрелась бы забавнее и правдивее.
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.