Комментарии 44
маркетинговая ловушка. Надо было 1-wire еще и в тэги добавить, но пока держусь :)
вообще, при нынешних ценах на чипы, можно запросто рядом с каждой кнопкой расположить какую-нибудь тиньку, которая принимала-отправляла бы команды модуляцией по питающему проводу
вообще, при нынешних ценах на чипы, можно запросто рядом с каждой кнопкой расположить какую-нибудь тиньку, которая принимала-отправляла бы команды модуляцией по питающему проводу
Я так поглядел, 1-Wire Slave довольно костыльно реализуется, а жаль.
что-то шутки даже со смайлом в конце предложения идут не очень — добавил определенности, закавычив широкоизвестное название протокола во избежание нежелательных ассоциаций.
А вообще, в данном случае достаточно именно «проволочного» решения на «клиентской стороне» — без всяких контроллеров в кнопках as long as все можно сделать аппаратно-программно на «сервере»
А вообще, в данном случае достаточно именно «проволочного» решения на «клиентской стороне» — без всяких контроллеров в кнопках as long as все можно сделать аппаратно-программно на «сервере»
так, на всякий случай, если кому-то интересно
человечек сделал клиента 1w на avr
avr.ru/ready/measure/mass/debet/part3
человечек сделал клиента 1w на avr
avr.ru/ready/measure/mass/debet/part3
Да их кто только не делал, и я в том числе (это следующий уровень после миганий светодиодами). Дать код на ассемблере? :)
дать!
хабр индексируется лучше очень многих ресурсов — легче найти новичкам
хабр индексируется лучше очень многих ресурсов — легче найти новичкам
Только вряд ли кому поможет кусок, вырванный из контекста, но ладно:
Код
; задержка в 1 микросекунду (максимально достижимой точности!!!)
; учитывается длительность RCALL и RET
; НЕ ДОЛЖНА ИСПОЛЬЗОВАТЬ НИ ОДНОГО РЕГИСТРА !!!!
; для низкой тактовой частоты, возможно, придется заменить на макрос из NOP-ов
delay1us:
; +3
nop ;1
push r0 ;2
pop r0 ;2
push r0 ;2 рассчитано ДЛЯ 20МГц!!!!!!
pop r0 ;2
push r0 ;2
pop r0 ;2
ret ;4 = 20 тактов (1 микросекунда)
;-------------------------------------------------------------------------------
delay10us:
; Задержка в 10 микросекунд (основана на delay1us) - повышенной точности!
; + 3
push wiretemp ; 2
ldi wiretemp, 9 ; 1 << для 20МГц!!!
d_loop: ;
rcall delay1us ; 8
dec wiretemp ; 1
brne d_loop ; 2/1
pop wiretemp ; 2
nop ; 1
nop ; 1
nop ; 1
ret ; 4
;-------------------------------------------------------------------------------
; задержка в wiretemp десятков микросекунд - повышенной точности не требуется
; вход: WireTemp = число десятков микросекунд для задержки (регистр портится)
;-------------------------------------------------------------------------------
delayus:
dec wiretemp
delayus1:
rcall delay10us
dec wiretemp
brne delayus1
rcall delay1us
rcall delay1us
rcall delay1us
rjmp delay1us
;-------------------------------------------------------------------------------
; выполняет выдачу сброса в линию 1-wire и возврат состояния PRESENCE
; вход: ничего
; выход: флаг Z установлен, если был PRESENCE
; так как длительность RESET может быть любой, прерывания не запрещаются,
; если это не необходимо
;-------------------------------------------------------------------------------
reset1w:
wire1
sbis wirepin,wirebit ; проверим наличие 1 в линии
rjmp presence_fault ; если нет - это ошибка
wire0 ; давим линию в 0
ldi wiretemp,49
rcall delayus ; 480 микросекунд задержка
wire1 ; линию в 1
ldi wiretemp,6
rcall delayus ; 60 микросекунд задержка
; начинаем ждать PRESENCE
ldi wiretemp,250 ; ждем с запасом
rw1_wait:
sbis wirepin,wirebit
rjmp presence_ok
rcall delay1us
dec wiretemp
brne rw1_wait
presence_fault:
; сюда мы попадаем, если не дождались PRESENCE
clz ; сбрасываем Z-флаг
ret
presence_ok:
; PRESENCE получен
sez
ldi wiretemp,49
rcall delayus
ret ; Z-флаг и так стоит
;-------------------------------------------------------------------------------
; выполняет прием байта из линии
; вход: ничего
; выход: r0 - принятый байт
;-------------------------------------------------------------------------------
resive1w:
ser wiretemp
mov r0,wiretemp
;-------------------------------------------------------------------------------
; выполняет передачу байта в линию
; вход: R0 - выводимый байт
; выход: R0 - то, что удалось ВВЕСТИ из линии
; портит: R0
; примечание: если делать ВЫВОД 0хFF, то на выходе будет ПРИНЯТЫЙ байт
;-------------------------------------------------------------------------------
send1w:
ldi wiretemp,8 ; число битов в байте (надо же :) )
sw1_next: ; сохраним флаги,
pushf ; т.к. будем запрещать прерывания
cli ; запрещаем прерывания
wire0 ; давим линию в 0
rcall delay1us ; 1 мкс задержки
ror r0 ; выталкиваем выводимый бит
brcc s0 ; если бит C = 0 - обход
wire1 ; линию в 1
s0:
push wiretemp
ldi wiretemp,9 ; в некоторых случаях может потребоваться
; увеличить это значение, но не более 13!
sw1_wait:
rcall delay1us
dec wiretemp
brne sw1_wait
clc
sbic wirepin,wirebit
sec
ror wireres
ldi wiretemp,9
rcall delayus ; 90 микросекунд - длительность тайм-слота
wire1
pop wiretemp
popf
dec wiretemp
brne sw1_next
mov r0,wireres
ret
;-------------------------------------------------------------------------------
; считывает 9 байтов в буфер, подсчитывает CRC
; портит r0 и SREG, регистры X и Z
;-------------------------------------------------------------------------------
readbytes1w:
clr wiretemp
sts CRC,wiretemp ; обнуляем CRC
ldiX Buffer
ldi wiretemp,9
r1w_next:
push wiretemp
rcall resive1w ; считываем 1 байт
; r0=считанному байту, начинаем подсчет CRC
st X+,r0 ; сохраняем принятый байт
rcall crc8 ; считаем контрольную сумму
pop wiretemp
dec wiretemp
brne r1w_next
ret
;-------------------------------------------------------------------------------
; выполняет подсчет CRC по алгоритму 1-Wire
; вход: r0 - считанный байт
; выход: CRC - содержит подсчитанную сумму
; портит: регистр Z
; примечание: перед первым вызовом CRC необходимо обнулить
;-------------------------------------------------------------------------------
crc8:
push r0
ldi wiretemp,8
mov wireres,wiretemp
r1w_loop_crc:
lds wiretemp,CRC
eor r0,wiretemp
ror r0
mov r0,wiretemp
brcc zero
ldi wiretemp,0x18
eor r0,wiretemp
zero:
ror r0
sts CRC,r0
pop r0
; 4 следующие команды делают циклический сдвиг r0
push r0
ror r0
pop r0
ror r0
; сдвиг закончен - очень удобно, не правда ли?!
push r0
dec wireres
brne r1w_loop_crc
pop r0
lds r0,CRC
ret
;-------------------------------------------------------------------------------
; Выбор датчика. Ссылка на массив с уникальным ID в Z
;-------------------------------------------------------------------------------
sel_sensor:
Send_1w CMD_MATCH_ROM ; Обращение к конкретному устройству
ldi r16,8
ss01:
lpm r0,Z+
rcall Send1w
dec r16
brne ss01
ret
Ага, а теперь то же самое с паразитным питанием, чтобы реально двумя проводами обойтись.
Где три провода, там и четыре, а где четыре — там и i2c или rs-485, без велосипедов.
Где три провода, там и четыре, а где четыре — там и i2c или rs-485, без велосипедов.
Я по подобному принципу лет 15 назад светодиод на выключатель освещения в квартире цеплял :)
А зачем вы шунтируете кнопкой и диод и резистор? Может только диод?
смысл в том, чтобы пересилить выход порта и притянуть его к нулю, и это притягивание заметил МК. Если просто закоротить диод, то резистор не позволит этого сделать — просто чуть увеличится выходной ток.
а почему бы не инвертировать режим работы вывода (т.е. переключить выход на вход) на те самые тестовые 20мс? и «перетягивать» ничего не придется
не получится — так как светодиод с резистором и так притянут вход к нулю, даже если включить внутренний pull-up — так как сопротивление pull-up'а на два-три порядка больше, чем гасящего резистора — в итоге, на нем почти ничего не упадет, плюс светодиод под микротоком (ну допустим, 1 вольт) — и МК не почувствует разницы между закороченным и свободным светодиодом — оба уровня будут ниже входного порога
пожалуй, а как на счет АЦП? должна же быть заметна разница!
можно, конечно, сместить диапазон delta-U при замкнутом и разомкнутом светодиоде так, чтобы он находился посередине порога переключения, например, включив в земляной провод 2-3 диода в прямом направлении.
Но, во-первых, это лишние элементы, во-вторых из монтажных соображений удобно, когда один из концов кнопки сидит на земле (корпусе), в третьих — помехозащищенность метода будет существенно хуже — смещение цифровой земли всего на 0.5 вольта (в начале статьи я упомянул про применение в автомобиле) сделает схему неработоспособной
Но, во-первых, это лишние элементы, во-вторых из монтажных соображений удобно, когда один из концов кнопки сидит на земле (корпусе), в третьих — помехозащищенность метода будет существенно хуже — смещение цифровой земли всего на 0.5 вольта (в начале статьи я упомянул про применение в автомобиле) сделает схему неработоспособной
У автора не 1-Wire, а «1-Wire», т.е. один провод. Всем известный протокол тут не при чём.
Именно. И у Maxim, создателя настоящего 1-Wire, есть микросхема, выполняющая функции, которые нужны автору.
При этом — все преимущества 1-Wire — готовые библиотеки, шина для нескольких устройств с авто-адресацией и, конечно, надёжность. Это всё оттестировано до нас и работает.
При этом — все преимущества 1-Wire — готовые библиотеки, шина для нескольких устройств с авто-адресацией и, конечно, надёжность. Это всё оттестировано до нас и работает.
А еще одного провода для собственного питания DS2413 часом не требует? ;)
Это прекрасно, а сам светодиод питать тоже паразиткой с шины? Чип-то получит команду на его включение, а кто даст энергию ему гореть? Или 1-wire переживет шунтирование светодиодом с резистором? ;)

Проблема высосана из пальца, извините
Вот код для дуни:
Симулятор: 123d.circuits.io/circuits/851507-pb-led
int state = 3; // просто индикатор состояния кнопки
int one_wire = 5; //"1 вайр"
// the setup routine runs once when you press reset:
void setup() {
// initialize the digital pin as an output.
pinMode(state, OUTPUT);
pinMode(one_wire, OUTPUT);
digitalWrite(one_wire, LOW);
}
// the loop routine runs over and over again forever:
void loop() {
pinMode(one_wire, INPUT);
digitalWrite(state, !digitalRead(one_wire));
pinMode(one_wire, OUTPUT);
delay(20);
}
Симулятор: 123d.circuits.io/circuits/851507-pb-led
Не извиняю — посчитайте количество проводов, связывающих кнопку-индикатор с МК системой в вашем случае
ээээ, 1?
Хочешь сказать, три? В твоем тогда два. В чем проблема цапануть +12В под приборкой для постоянной индикации без всяких выкрутасов?
Хочешь сказать, три? В твоем тогда два. В чем проблема цапануть +12В под приборкой для постоянной индикации без всяких выкрутасов?
В чем проблема цапануть +12В под приборкой для постоянной индикации без всяких выкрутасов?
Только вот надо +5, а не +12.
Так надо, чтобы подсветка всегда работала или время от времени? Если всегда, то хоть 220. А если время от времени, то моя схема не пойдет — подсветка будет гореть всегда, когда кнопка нажата.
Можно узнать модель кнопки. Спасибо.
Последнюю схему не понял. Как при одном входе понять, какая кнопка нажата?
Сканировать по очереди, например.
Но если кнопок много, то и линий много, проще коммутатор сделать и передавать уже настоящей 1-wire
Но если кнопок много, то и линий много, проще коммутатор сделать и передавать уже настоящей 1-wire
Так а что сканировать по очереди, если физический вход один? Например, что мы получим в случае, если нажато несколько кнопок одновеременно?
Ха… все выходные не мог дочитать статью до конца, а особенно комментарии…
Товарищи! Вы где усыпили своего инженера?
Не надо ничего замыкать! Подключите кнопкой параллельно светодиоду и резистору… конденсатор! Он не шунтирует цепь, по крайней мере надолго, и если ограничить ток его заряда резистором в 100 Ом он вообще не будет создавать нагрузку порту и мешать светодиоду. Зато его наличие легко определяется по инерционности — когда светодиод включен, короткое отключение порта в режим входа и через определенное время смотрим — есть напряжение, значит кнопка замкнута нет напряжения — кнопка разомкнута.
Если светодиод погашен — выдаем короткий импульс «1» по окончанию импульса через несколько микросекунд смотрим — есть напряжение(паразитная емкость быстро зарядится, но будет держать заряд еще считанные микросекунды) значит кнопка разомкнута, если зарядится не успеет — копка замкнута и подключен значительно больший конденсатор, которому не хватило времени чтобы зарядится.
Немного усложнит опрос кнопки но… преимущества на лицо.
Товарищи! Вы где усыпили своего инженера?
Не надо ничего замыкать! Подключите кнопкой параллельно светодиоду и резистору… конденсатор! Он не шунтирует цепь, по крайней мере надолго, и если ограничить ток его заряда резистором в 100 Ом он вообще не будет создавать нагрузку порту и мешать светодиоду. Зато его наличие легко определяется по инерционности — когда светодиод включен, короткое отключение порта в режим входа и через определенное время смотрим — есть напряжение, значит кнопка замкнута нет напряжения — кнопка разомкнута.
Если светодиод погашен — выдаем короткий импульс «1» по окончанию импульса через несколько микросекунд смотрим — есть напряжение(паразитная емкость быстро зарядится, но будет держать заряд еще считанные микросекунды) значит кнопка разомкнута, если зарядится не успеет — копка замкнута и подключен значительно больший конденсатор, которому не хватило времени чтобы зарядится.
Немного усложнит опрос кнопки но… преимущества на лицо.
Да, динамикой можно красиво решить задачу — однако суть моей идеи в том, что в месте установки кнопки не нужно никаких дополнительных элементов вообще — так как гасящий резистор уже есть внутри кнопки. Массовый провод подкладывается под гайку крепления, и в МК систему идет всего один провод, а все остальное делается чисто программно. Долгого шунтирования же цепи не будет, т.к. алгоритм обработки нажатия, увидев первое, переведет выходной порт в 0, с короткими 1 только на время очередного опроса. Я вижу существенное преимущество вашего решения только в следующем (помимо того, что оно, конечно, красивое) — в возможности выполнять индикацию от МК системы в то время, пока кнопка нажата — если это в силу каких-то причин необходимо, то стоит выбрать его
И чтобы не писать несколько ответов — кнопки такие продаются на aliexpress.com, а вариант схемы с одним входом, развязанном диодами, конечно, работать не будет — это я загнул. Нужно будет использовать первый или второй вариант
BTW, некоторые кнопки имеют НЗ контакты (но они вроде как дороже, чем НР) — их можно включить последовательно со светодиодом/резистором, и проверять порт в режиме чтения на 1
И чтобы не писать несколько ответов — кнопки такие продаются на aliexpress.com, а вариант схемы с одним входом, развязанном диодами, конечно, работать не будет — это я загнул. Нужно будет использовать первый или второй вариант
BTW, некоторые кнопки имеют НЗ контакты (но они вроде как дороже, чем НР) — их можно включить последовательно со светодиодом/резистором, и проверять порт в режиме чтения на 1
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
«1-wire» для кнопок с индикацией