ПРОЦЕСС ЗАКАЗА ПЕЧАТНЫХ ПЛАТ С КИТАЯ JLCPCB+DIPTRACE

 Arduino  Комментарии к записи ПРОЦЕСС ЗАКАЗА ПЕЧАТНЫХ ПЛАТ С КИТАЯ JLCPCB+DIPTRACE отключены
Мар 162020
 

Изготавливать платы в китае очень удобно. Заводское качество и многослойность безусловно превосходит домашние варианты изготовления плат ЛУТом.

Первым делом необходимо спроектировать плату в любом удобном редакторе, для меня это DipTrace.

Выбираем экспорт в Gerber формат.

Выбираем настройки файлов экспорта.

Т.к. Diptrace экспортирует много лишней информации, которую китайцы не используют при изготовлении плат — выключаем ненужные по скриншоту. Также, переименовываем расширения файлов в соответствии со скриншотом, по ним на заводе быстро определяют какой гербер файл за что отвечает, это ускоряет процесс изготовления и снижает шанс отказа по заказу.

Сохраняем и нажимаем «Экспорт всех», сохраняем файлы в отдельную папку.

Начинаем экспорт схемы рассверловки платы.

Нажимаем Авто, далее экспортируем, обязательно сохраняем файл с именем проекта и расширением .XLN

В итоге мы получили следующие файлы:

Архивируем файлы в ZIP, подготовка платы завершена, можно заказывать изготовление платы.

Регистрируемся и входим на сайт JLCPCB https://jlcpcb.com/.

Заходим на страницу калькулятора https://jlcpcb.com/quote и выбираем наш архив с гербер файлами.

Калькулятор отобразит макет платы и предложит выбрать параметры её изготовления.

Параметры на странице следующие, меняя их меняется и стоимость заказа, отображаемая в правой колонке:

  • Layers — количество металлизированных слоёв платы;
  • Dimensions — размеры, оставляем по умолчанию размеры из Gerber файла;
  • PCB Qty — количество плат к заказу;
  • PCB Thickness — толщина текстолита в миллиметрах;
  • PCB Color — цвет платы/паяльной маски;
  • Surface Finish — покрытие контактных площадок;
  • Copper Weight — количество меди на дорожках;
  • Gold Fingers — позолота контактных площадок;
  • Material Details — тип текстолита, обычно FR4;
  • Panel By JLCPCB — нужно при изготовлении нескольких плат на одной панели текстолита;
  • Flying Probe Test — тестирование соединений на плате роботом;
  • Castellated Holes — отверстия не на всю толщину платы, требуется при монтаже некоторых BGA микросхем;
  • Different Design — количество плат в одном гербер файле;

После этого можно перемещать заказ в корзину и оплачивать.

Процесс изготовления платы можно контролировать в личном кабинете:

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

В итоге придёт коробка с заказанными платами, упакованными под вакуумом, а также небольшой подарок в виде фирменной ручки или стикеров.


PCBКИТАЙJLCPCBDIPTRACEТРАНСИВЕР UA3REO

Схемы управления питанием

 Arduino  Комментарии к записи Схемы управления питанием отключены
Фев 112020
 

С батарейным питанием все замечательно, кроме того, что оно кончается, а энергию надо тщательно экономить. Хорошо когда устройство состоит из одного микроконтроллера — отправил его в спячку и все. Собственное потребление в спящем режиме у современных МК ничтожное, сравнимое с саморазрядом батареи, так что о заряде можно не беспокоиться. Но вот засада, не одним контроллером живо устройство. Часто могут использоваться разные сторонние периферийные модули которые тоже любят кушать, а еще не желают спать. Прям как дети малые. Приходится всем прописывать успокоительное. О нем и поговорим.

▌Механическая кнопка
Что может быть проще и надежней сухого контакта, разомкнул и спи спокойно, дорогой друг. Вряд ли батарейку раскачает до того, чтобы пробить миллиметровый воздушный зазор. Урания в них для этого не докладывают. Какой нибудь PSW переключатель то что доктор прописал. Нажал-отжал.

psw.JPG

Вот только беда, ток он маленький держит. По паспорту 100мА, а если запараллелить группы, то до 500-800мА без особой потери работоспособности, если конечно не клацать каждые пять секунд на реактивную нагрузку (катушки-кондеры). Но девайс может кушать и поболее и что тогда? Приматывать синей изолентой к своему хипстерскому поделию здоровенный тумблер? Нормальный метод, мой дед всю жизнь так делал и прожил до преклонных лет.

▌Кнопка плюс
Но есть способ лучше. Рубильник можно оставить слабеньким, но усилить его полевым транзистором. Например вот так.

button.png

Тут переключатель просто берет и поджимает затвор транзистора к земле. И он открывается. А пропускаемый ток у современных транзисторов очень высокий. Так, например, IRLML5203 имея корпус sot23 легко тащит через себя 3А и не потеет. А что-нибудь в DPACK корпусе может и десяток-два ампер рвануть и не вскипеть. Резистор на 100кОм подтягивает затвор к питанию, обеспечивая строго определенный уровень потенциала на нем, что позволяет держать транзистор закрытым и не давать ему открываться от всяких там наводок.

▌Плюс мозги
Можно развить тему управляемого самовыключения, таким вот образом. Т.е. устройство включается кнопкой, которая коротит закрытый транзистор, пуская ток в контроллер, он перехватывает управление и, прижав ногой затвор к земле, шунтирует кнопку. А выключится уже тогда, когда сам захочет. Подтяжка затвора тоже лишней не будет. Но тут надо исходить из схемотехники вывода контроллера, чтобы через нее не было утечки в землю через ногу контроллера. Обычно там стоит такой же полевик и подтяжка до питания через защитные диоды, так что утечки не будет, но мало ли бывает…

onlymcu.png

Или чуть более сложный вариант. Тут нажатие кнопки пускает ток через диод на питание, контроллер заводится и сам себя включает. После чего диод, подпертый сверху, уже не играет никакой роли, а резистор R2 эту линию прижимает к земле. Давая там 0 на порту если кнопка не нажата. Нажатие кнопки дает 1. Т.е. мы можем эту кнопку после включения использовать как нам угодно. Хоть для выключения, хоть как. Правда при выключении девайс обесточится только на отпускании кнопки. А если будет дребезг, то он может и снова включиться. Контроллер штука быстрая. Поэтому я бы делал алгоритм таким — ждем отпускания, выбираем дребезг и после этого выключаемся. Всего один диод на любой кнопке и нам не нужен спящий режим 🙂 Кстати, в контроллер обычно уже встроен этот диод в каждом порту, но он очень слабенький и его можно ненароком убить если вся ваша нагрузка запитается через него. Поэтому и стоит внешний диод. Резистор R2 тоже можно убрать если нога контроллера умеет делать Pull-down режим.

cpuplus.png

▌Отключая ненужное
Можно сделать и по другому. Оставить контроллер на «горячей» стороне, погружая его в спячку, а обесточивать только жрущую периферию.

hotmcu.png

Выделив для нее отдельную шину питания. Но тут надо учесть, что есть такая вещь как паразитное питание. Т.е. если вы отключите питание, например, у передатчика какого, то по шине SPI или чем он там может управляться пойдет питание, поднимется через защитные диоды и периферия оживет. Причем питания может не хватить для его корректной работы из-за потерь на защитных диодах и вы получите кучу глюков. Или же получите превышение тока через порты, как результат выгоревшие порты на контроллере или периферии. Так что сначала выводы данных в Hi-Z или в Low, а потом обесточивайте.

▌Выкидываем лишнее
Что-то мало потребляющее можно запитать прям с порта. Сколько дает одна линия? Десяток миллиампер? А две? Уже двадцать. А три? Параллелим ноги и вперед. Главное дергать их синхронно, лучше за один такт.

gpios.png

Правда тут надо учитывать то, что если нога может отдать 10мА ,то 100 ног не отдадут ампер — домен питания не выдержит. Тут надо справляться в даташите на контроллер и искать сколько он может отдать тока через все выводы суммарно. И от этого плясать. Но до 30мА с порта накормить на раз два.

Главное не забывайте про конденсаторы, точнее про их заряд. В момент заряда кондера он ведет себя как КЗ и если в вашей периферии есть хотя бы пара микрофарад емкостей висящих на питании, то от порта ее питать уже не следует, можно порты пожечь. Не самый красивый метод, но иногда ничего другого не остается.

▌Одна кнопка на все. Без мозгов
Ну и, напоследок, разберу одно красивое и простое решение. Его несколько лет назад набросил мне в комменты uSchema это результат коллективного творчества народа на его форуме.

1button.png

Одна кнопка и включает и выключает питание.

Как работает:

При включении, конденсатор С1 разряжен. Транзистор Т1 закрыт, Т2 тоже закрыт, более того, резистор R1 дополнительно подтягивает затвор Т1 к питанию, чтобы случайно он не открылся.

Конденсатор С1 разряжен. А значит мы в данный момент времени можем считать его как КЗ. И если мы нажмем кнопку, то пока он заряжается через резистор R1 у нас затвор окажется брошен на землю.

1bt1.png

Это будет одно мгновение, но этого хватит, чтобы транзистор Т1 распахнулся и на выходе появилось напряжение. Которое тут же попадет на затвор транзистора Т2, он тоже откроется и уже конкретно так придавит затвор Т1 к земле, фиксируясь в это положение. Через нажатую кнопку у нас С1 зарядится только до напряжения которое образует делитель R1 и R2, но его недостаточно для закрытия Т1.

1bt2.png

Отпускаем кнопку. Делитель R1 R2 оказывается отрезан и теперь ничто не мешает конденсатору С1 дозарядиться через R3 до полного напряжения питания. Падение на Т1 ничтожно. Так что там будет входное напряжение.

1bt3.png

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

Жмем кнопку еще раз. Теперь уже заряженный на полную конденсатор С1 вбрасывает все свое напряжение (а оно равно напряжению питания) на затвор Т1. Открытый транзистор Т2 тут вообще не отсвечивает, ведь он отделен от этой точки резистором R2 аж на 10кОм. А почти нулевое внутреннее сопротивление конденсатора на пару с его полным зарядом легко перебивает низкий потенциал на затворе Т1. Там кратковременно получается напряжение питания. Транзистор Т1 закрывается.

Тут же теряет питание и затвор транзистора Т2, он тоже закрывается, отрезая возможность затвору Т1 дотянуться до живительного нуля. С1 тем временем даже не разряжается. Транзистор Т2 закрылся, а R1 действует на заряд конденсатора С1, набивая его до питания. Что только закрывает Т1.

1bt4.png

Отпускаем кнопку. Конденсатор оказывается отрезан от R1. Но транзисторы все закрыты и заряд с С1 через R3 усосется в нагрузку. С1 разрядится. Схема готова к повторному включению.

1bt5.png

Вот такая простая, но прикольная схема. Вот тут еще полно реализаций похожих схем. На сходном принципе действия.

Программирование регистра конфигурации датчика температуры DS18B20.

 Arduino  Комментарии к записи Программирование регистра конфигурации датчика температуры DS18B20. отключены
Фев 082020
 

Программирование регистра конфигурации датчика температуры DS18B20.

Сообщение Эдуард » 21 янв 2017, 23:32

Разрешающая способность датчика температуры DS18B20 может быть задана в регистре конфигурации. Возможны варианты: 9, 10, 11 и 12 битов.

От этого параметра зависит точность измерения температуры. Но при повышении разрешения увеличивается и время измерения. Для каждой конкретной задачи лучше выбирать свою разрешающую способность датчика.

Регистр конфигурации загружается при включении питания из внутреннего EEPROM датчика DS18B20. Можно, конечно, программировать EEPROM датчика в устройстве, к которому он подключен, но это лишняя операция, занимающая время и ресурсы. Практичнее запрограммировать конфигурацию датчика отдельно.

Для этого я написал не большую программу. Она загружается в плату Arduino UNO R3 и получается простой программатор.

Датчик DS18B20 подключается по такой схеме.
ProgDs18b20_5.PNG
ProgDs18b20_5.PNG (6.53 КБ) 4417 просмотров

Я выбрал выводы, для того чтобы датчик можно было просто вставить в соседние контакты разъема платы. Туда же вставляется резистор сопротивлением 4,3 кОм.
ProgDs18b20_4.JPG

ProgDs18b20_3.JPG

Загружается программа в плату. Открывается монитор последовательного порта Arduino IDE. Скорость 9600 бод.
Программа в цикле считывает состояние датчика: температуру и разрешающую способность (в разрядах).
ProgDs18b20_1.PNG

Для программирования необходимо послать команду:

  • D=0 , для установки разрешения 9 бит;
    D=1 , для установки разрешения 10 бит;
    D=2 , для установки разрешения 11 бит;
    D=3 , для установки разрешения 12 бит.

В окне монитора должно появиться сообщение ”Programming” и произойти собственно программирование. После этого будут отображаться новые данные разрешения датчика.
ProgDs18b20_2.PNG

Все остальные команды программа проигнорирует.
Вот скетч программы.

КОД: ВЫДЕЛИТЬ ВСЁ

// программирование датчика DS18B20
#include <OneWire.h>

OneWire sensDls (13); // датчик подключен к выводу 13

byte buffData[9]; // буфер данных
float temperature; // измеренная температура

void setup() {
Serial.begin(9600); // инициализируем порт, 9600 бод
pinMode(12, OUTPUT);
digitalWrite(12, HIGH);
}

void loop() {

// перезагрузка данных из EEPROM
sensDls.reset(); // сброс шины
sensDls.write(0xCC, 0); // пропуск ROM
sensDls.write(0xB8, 0); // запись EEPROM
delay(20);

// чтение данных из датчика
sensDls.reset(); // сброс шины
sensDls.write(0xCC, 0); // пропуск ROM
sensDls.write(0x44, 0); // инициализация измерения
delay(900); // пауза 0,9 сек
sensDls.reset(); // сброс шины
sensDls.write(0xCC, 0); // пропуск ROM
sensDls.write(0xBE, 0); // команда чтения памяти датчика
sensDls.read_bytes(buffData, 9); // чтение памяти датчика, 9 байтов

if ( OneWire::crc8(buffData, 8) == buffData[8] ) { // проверка CRC
// данные правильные
Serial.print("T= ");
Serial.print((float)((int)buffData[0] | (((int)buffData[1]) << 8)) * 0.0625 + 0.03125);

Serial.print(" Digits= ");
if ( (buffData[4] & 0x60) == 0) Serial.println("9");
else if ( (buffData[4] & 0x60) == 0x20) Serial.println("10");
else if ( (buffData[4] & 0x60) == 0x40) Serial.println("11");
else if ( (buffData[4] & 0x60) == 0x60) Serial.println("12");
}

else {
// ошибка CRC
Serial.println("Read error");
}

// проверка данных для программирования
if( Serial.available() != 0) {
delay(10);

if( Serial.available() == 5) {
// все правильно, 5 байтов

if ( (Serial.read() == 'D') && (Serial.read() == '=') ) {

char x = Serial.read();
if ( (x == '0') || (x == '1')|| (x == '2')|| (x == '3') ) {

// программирование
// загрузка данных в ОЗУ
sensDls.reset(); // сброс шины
sensDls.write(0xCC, 0); // пропуск ROM
sensDls.write(0x4E, 0); // запись памяти
sensDls.write(0, 0); // TL
sensDls.write(0, 0); // TH

if (x == '0') sensDls.write(0x1F, 0);
else if (x == '1') sensDls.write(0x3F, 0);
else if (x == '2') sensDls.write(0x5F, 0);
else if (x == '3') sensDls.write(0x7F, 0);
delay(20);

// загрузка данных в EEPROM
sensDls.reset(); // сброс шины
sensDls.write(0xCC, 0); // пропуск ROM
sensDls.write(0x48, 0); // запись EEPROM

delay(50);
Serial.println("Programming");
}
else {
// ошибка
while (true) { if (Serial.read() == 0xffff) break;}
}
}
else {
// не правильно
while (true) { if (Serial.read() == 0xffff) break;}
}
}
else {
// не правильно
while (true) { if (Serial.read() == 0xffff) break;}
}
}
}

ПРОТОКОЛ 1-WIRE

 Arduino  Комментарии к записи ПРОТОКОЛ 1-WIRE отключены
Фев 072020
 

ПРОТОКОЛ 1-WIRE

1-Wire – протокол передачи данных в обе стороны по одному проводу.

Данный протокол разработан корпорацией Dallas Semiconductor (сейчас Maxim Integrated) в далёких 90-х, но активно используется и сейчас: именно на 1-Wire работает большинство «таблеток» — домофонных чипов (DS1990A), карточек доступа, а также через 1-Wire общаются популярные датчики температуры (DS18S20 и DS18B20), транзисторные ключи (DS2405, DS2406), программируемые порты ввода-вывода (DS2408), АЦП и ЦАП, часы реального времени (DS2417) и многое другое.

Режим связи в этом протоколе – асинхронный и полудуплексный (об этом подробнее тут), а также «остроконечный» (при отсылке многобайтовых целых передача идёт от младшего байта к старшему).

При этом у нас всегда есть ведущий – одно устройство на шине, которое отсылает команды, и ведомые – устройства, которые эти команды принимают и отвечают на них, если необходимо; каждое из ведомых устройств подключается непосредственно к общей шине.

Ещё раз подчеркнём – на шине может быть только ОДИН ведущий – иначе возникнут конфликты, когда оба ведущих будут тянуть одеяло на себя (на самом деле, есть некоторые приёмы организации сетей 1-Wire в режиме мультимастера – например, с помощью ветвителя сети DS2409 – но в «обычной» жизни все-таки предпочтительней иметь только одного ведущего на шине).

Протокол 1-Wire хорош тем, что не сложен в реализации и требует для связи всего два-три провода (шина данных, земля и при необходимости питание); однако при этом он не лишён и недостатков – этот протокол весьма чувствителен ко времени и к помехам. Также 1-Wire не предназначена для передачи больших объёмов информации и для скоростного обмена данными – максимальная скорость 9600 Бод/с.

Протокол 1-Wire описывает физический, канальный, сетевой и транспортный уровни взаимодействия (см. модель OSI).
На физическом уровне даются описания способов подключения, требования к шине данных и питанию и т.д.
Канальный уровень описывает способы чтения и передачи битов по протоколу.
Сетевой уровень описывает способы адресации к различным устройствам на линии.
Наконец, транспортный уровень описывает функциональные команды, используемые устройствами 1-Wire.

ФИЗИЧЕСКИЙ УРОВЕНЬ ПРОТОКОЛА

Физически для организации интерфейса необходимы как минимум линия для данных и «земля»; достаточно часто также для подключения устройств необходима также линия питания, однако некоторые ведомые устройства могут питаться и паразитно – получать «подпитку» через шину данных.

1-Wire%20-%20Connection%20example.png
Рисунок 1. Пример подключения ведущего и ведомых устройств по протоколу 1-Wire.

Упрощенный пример подключения шины представлен на рисунке 1: так, у нас есть ведущее устройство и три ведомых, Slave1, Slave2 и Slave3. Шина данных (data) подтянута резистором к питанию и к ней присоединены все четыре устройства; также каждое из устройств подсоединено к земле. Master, Slave2 и Slave3 подключены к питанию (от 3 до 5 В, в зависимости от требований устройств), а устройство Slave1 питается паразитно через шину данных (об этом подробнее ниже).

К слову, о питании – согласно даташиту, шина данных должна быть подтянута к питанию резистором 4.7 кОм, однако данный номинал используется при относительно коротких линиях; если же расстояние между устройствами достаточно велико, то сопротивление резистора можно уменьшить.

КАНАЛЬНЫЙ УРОВЕНЬ ПРОТОКОЛА

Обмен информацией ведётся так называемыми временными, или тайм-слотами (60 мкс): один тайм-слот служит для обмена одним битом информации. Данные передаются бит за битом, начиная с младшего бита младшего байта – это, кстати, достаточно часто приводит к ошибкам у новичков – кажется, что нужно передавать данные слева направо, так, как они хранятся в памяти (то есть, следите за словами: кажется, что нужно начинать со старшего бита младшего байта (вы уже запутались, да?) – но нет! При передаче по 1-Wire, например, двухбайтового числа порядок передачи будет таким:
Имеем число 1023410 – в двоичном виде выглядит так: 00100111 111110102
В памяти (так как у нас «остроконечный» порядок хранения данных) выглядит так: 11111010 00100111.
А передача по 1-Wire будет выглядеть так:
0→1→0→1→1→1→1→1→1→1→1→0→0→1→0→0
Если вы запутались так же, как и я – самое время выпить чая с шоколадкой и немного утрясти все в голове.

Идём дальше. При обмене информацией ведущий инициирует каждую связь на битном уровне. Это означает, что передача каждого бита, независимо от направления (передача или приём), должна быть инициирована ведущим. Шина данных по умолчанию подтягивается к «единице», поэтому для начала как приёма, так и для передачи ведущий опускает линию в «ноль» на некоторое время.

Внимание: ни ведущий, ни ведомые не выставляют на шине «единицу» — это черевато коротким замыканием: если одно устройство выставит на шине «1», а другое – «0»; поэтому как ведущий, так и ведомый могут использовать только два состояния: «на выход в ноль» и «z-состояние» (на вход без подтяжки). Подтяжка к питанию осуществляется резистором (!).

Рассмотрим 5 основных команд для связи по шине 1-Wire: «Запись 1», «Запись 0», «Чтение», «Сброс» и «Присутствие». При этом на рисунках красным выделено управление линией от ведущего, синим – управление линией от ведомого, черным – освобожденная линия (с помощью подтяжки шина автоматически переходит в «единицу»).

Сигнал «Запись 1». Ведущий устанавливает низкий уровень в течение 1…15 мкс. После этого, в течение оставшейся части временного слота он освобождает шину.

1-Wire%20-%20Write%201.png

Сигнал «Запись 0». Ведущий формирует низкий уровень в течение не менее 60 мкс, но не дольше 120 мкс.

1-Wire%20-%20Write%200.png

Сигнал «Чтение». Ведущий устанавливает низкий уровень в течение 1…15 мкс. После этого подчинённый, если хочет передать 0, удерживает шину в низком состоянии до 60 мкс; если же подчинённых хочет передать 1, то он просто освобождает линию. Ведущий обычно сканирует состояние шины по истечении 15 мкс после установки низкого уровня на шине.
1-Wire%20-%20Read.png

Так, ведомый удерживает линию к земле, если хочет передать «0», и просто отпускает линию, если хочет передать «1».
Таким образом при чтении получаем следующие диаграммы.

Сигнал «Чтение при получении 1»:

1-Wire%20-%20Read%201.png

Сигнал «Чтение при получении 0»:

1-Wire%20-%20Read%200.png

Основные проблемы, которые возникают при реализации чтения-записи – это проблемы со временем, то есть «невыдерживание», или наоборот, «передерживание» временных задержек при чтении линии. Возникают эти проблемы из-за того, что часто не делают поправку на медленность языков программирования высокого уровня. Особенно это касается различных «дополнительных» функций и ништяков. Подробнее тут

Сигнал «Сброс/присутствие». Здесь временные интервалы импульсов отличаются. Ведущий устанавливает низкий уровень в течение 8 временных слотов (480 мкс), а затем освобождает шину. Данный длительный период низкого состояния называется сигнал «Сброс».
Если на шине присутствует подчинённый, то он должен в течение 60 мкс после освобождения ведущим шины установить низкий уровень длительностью не менее 60 мкс. Данный отклик носит название «Присутствие». Если такой сигнал не обнаруживается, то ведущий должен полагать, что нет подключённых устройств к шине и дальнейшая связь невозможна.
Данная связка сигналов всегда начинает любой обмен информацией между устройствами.
Помимо этого, нужно учитывать, что любое ведомое устройство после получения питания сразу же выдаёт сигнал присутствия.
Сигнал же «Сброс» позволяет ведущему досрочно завершить обмен информацией – например, если датчик температуры передаёт нам всю свою память, а нам нужны только первые два байта, которые содержат значение температуры, то после получения этих двух байт микросхема просто может опустить линию в ноль на нужное количество времени – датчик поймет, что больше ничего пересылать не нужно.

1-Wire%20-%20Reset-Presence.png

О реализации: обычно необходимо запрограммировать микроконтроллер как ведущее устройство, поэтому есть несколько советов: микроконтроллеру стоит генерировать сигналы (опускание шины к земле) чуть больше необходимого минимума по времени, а ответы от ведомых устройств ждать по наихудшим прогнозам – тогда взаимодействие по протоколу будет оптимальным.
При этом ведущему нужно не забывать периодически проверять состояние линии данных — то, что она возвращается в подтянутое состояние с течением времени – а то может возникнуть ситуация, например, что какой-нибудь ведомый сломался и коротит, например, линию в ноль – и в принципе, протокол не проверяет данную проблему сам, ошибки может и не возникнуть – но об этом чуть ниже.

СЕТЕВОЙ И ТРАНСПОРТНЫЙ УРОВНИ ПРОТОКОЛА

Рассмотрим «более высокий» уровень протокола 1-Wire – последовательность действий при взаимодействии ведущего и ведомого, а также основные команды. При этом нужно отметить, все данные, в том числе команды, отсылаются побитно последовательно, начиная с младшего бита.

Алгоритм взаимодействия:

  1. Ведущий посылает на линию сигнал reset («Сброс»). После линия освобождается для «ответных действий». Если на шине присутствует ведомый, то в течение 60 мкс он сообщает о «присутствии».
    Если же ведущий не получает отклика-«присутствия», то он считает, что подключённых к шине устройств нет.
  2. Далее следует сетевой уровень протокола: ведущий должен определить, к какому из устройств на шине данных он будет дальше обращаться. Данный выбор обеспечивается отсылкой одной из ROM-команд (длиной в 1 байт), которые работают с уникальными кодами устройств:
    • Search ROM ($F0) – «поиск ROM». Если коды подключённых устройств не известны, то эта команда позволяет ведущему определить их. Подробное описание данной команды представлено ниже.
    • Read ROM ($33) – «чтение ROM» – команда используется, если мы точно знаем, что у нас только одно подчинённое устройство (например, только один датчик температуры или один домофонный ключ), тогда для считки его кода можно не париться с поиском ROM. При получении данной команды все ведомые устройства на шине отсылают свой уникальный код.
    • Skip ROM ($CC) – «пропуск ROM». Это команда используется, когда необходимо дать команду всем устройствам на шине – например, нужно, чтобы все подключённые датчики одновременно считали температуру.
    • Match ROM ($55) – «совпадение ROM». Используется для выбора конкретного подчинённого устройства на шине. После отсылки команды ведущий передаёт 64-разрядный код. По завершении только тому подчинённому устройству, которое приняло свой идентификатор, разрешается отвечать после приёма следующего импульса сброса – остальные же молча ждут импульса сброса.

    Естественно, для отдельных устройств какие-то ROM-команды могут добавляться.

  3. Если были отправлены команды «Match ROM» или «Skip ROM», то далее ведущий отправляет какую-либо функциональную команду – это уже транспортный уровень протокола; при этом набор функциональных команд и дальнейшее поведение (должен ли ведущий быть готов принимать данные от выбранного ведомого устройства, например) зависит от конкретного устройства 1-Wire.

Так, например, если у нас есть микроконтроллер и DS18S20 – датчик температуры, и мы хотим получить от этого датчика значение температуры, то алгоритм работы будет следующим:

  1. МК отсылает импульс сброса
  2. Датчик отвечает импульсом приветствия
  3. МК отсылает адресную команду «Skip ROM» — так как датчик у нас на линии один, то нам нет необходимости работать с «адресами»
  4. МК отсылает функциональную команду «Convert T» — по этой команде датчик температуры начнёт однократное температурное преобразование; результат же этого преобразования будет записан в память датчика
  5. МК ждёт, пока датчик закончит преобразование (ведомое устройство никоим образом не может само сообщить, что оно «освободилось», поэтому микроконтроллер просто ждёт время, указанное в даташите)
  6. МК отсылает импульс сброса
  7. Датчик отвечает импульсом приветствия
  8. МК отсылает адресную команду «Skip ROM»
  9. МК отсылает функциональную команду «Read Scratchpad» — по этой команде датчик отсылает 9 байт своей памяти
  10. МК считывает нужное количество байт (значение температуры содержится в первых двух)
  11. При необходимости МК завершает сеанс связи, отсылая импульс сброса

При этом нужно помнить, что ведомые устройства могут поломаться и, например, опускать линию всегда на 0. Допустим, у нас так закоротило датчик температуры в термостате печки. Тогда, если ведущий не проверит, что линия возвращается в единицу, то вероятна следующая ситуация:

  1. МК отсылает импульс сброса
  2. Датчик коротит линию на ноль – МК обнаруживает, что есть импульс приветствия
  3. МК отсылает адресную команду «Skip ROM» — не проверяя при этом линию, конечно
  4. МК отсылает функциональную команду «Convert T» — датчик всё ещё в коме
  5. МК ждёт
  6. МК отсылает импульс сброса
  7. история повторяется, датчик отсылает ноль
  8. МК отсылает адресную команду «Skip ROM»
  9. МК отсылает функциональную команду «Read Scratchpad»
  10. МК считывает нужное количество байт — и получает, естественно, все нули. Даже если мы считываем всю память вместе с CRC, CRC от нуля будет равно нулю – то есть ошибки не произойдет МК конвертирует температуру, получает ноль, отправляет команду нагревать печь. И так до бесконечности!

Выглядит все это довольно печально – и черевато большими проблемами! Так что на протокол полагайся, но сам не плошай.

Вернёмся к алгоритму взаимодействия ведущего и ведомого по протоколу. Как видно, реализовать работу ведущего устройства не так уж сложно – при этом есть как уже готовые библиотеки с кодом, так и аппаратные реализации – например, от той же фирмы Maxim Integrated. Так, например, для AVR-ок написан целый даташит для реализации 1-Wire.

А вот реализовать ведомое устройство не так уж просто – и если библиотеки существуют (например, у нас на сайте), то аппаратных реализаций именно протокола 1-Wire мне не встречалось. Принцип же работы ведомых устройств подробно описан в их документации, обычно в виде блок-схемы.

ПАРАЗИТНОЕ ПИТАНИЕ

Протокол 1-Wire позволяет ведомым устройствам при необходимости использовать паразитное питание – так, например, если уже есть линия с двумя проводами, или же необходимо удалённое измерение, или, например, в случае системы аутентификации, ведомое устройство (ключ или карточка) не подразумевает подключение питания.

Каждое устройство имеет свои требования к паразитному питанию, но обычно это требование не опускать линию данных в ноль в течение выполнения ведомым определённых функциональных команд.

Например, для датчика температуры DS18S20, использующего протокол 1-Wire, необходимо гарантировать, что на шине данных будет достаточное напряжение при выполнении температурного преобразования или при копировании данных из памяти EEPROM. Согласно даташиту, при этом рекомендуется подтягивать линию данных к питанию с помощью полевого транзистора; на деле же при использовании напряжения +5-+5.5 В микроконтроллеру достаточно просто не опускать шину данных в ноль (в случае именно с датчиком DS18S20 – другие датчики могут потреблять больше тока). Также именно паразитное питание является одной из причин, почему микроконтроллеру стоит передавать сигналы (то есть опускать линию данных в ноль) по минимальному времени – это позволяет устройствам на паразитном питании нормально функционировать.

К слову, не все авторы библиотек заморачиваются данным вопросом – так, при попытке заставить работать датчик DS18S20 на паразитном питании в среде MikroElectronika с использованием библиотеки этой среды датчик просто не получал достаточного питания и не мог нормально «общаться».

ОБЛАСТИ ПРИМЕНЕНИЯ

Существует целый ряд устройств, использующих интерфейс 1-Wire, — так, например, всем известная «таблетка» — домофонный ключ – работает в большинстве случаев именно через данный протокол: микроконтроллер в замке просто спрашивает уникальный код «таблетки», и если этот код содержится в списке разрешённых устройств, микроконтроллер открывает замок.

Помимо всевозможных устройств для идентификации и авторизации (ключи, карточки пропуска), многие датчики – будь то датчики температуры, датчики влажности, освещения и др. – также используют для связи интерфейс 1-Wire. Помимо этого, есть также ряд микросхем для «мониторинга, менеджмента, защиты и управления восстановлением заряда автономных источников питания самых различных типов и назначений».

УНИКАЛЬНЫЕ КОДЫ УСТРОЙСТВ 1-WIRE

Пару слов об уникальных кодах устройств, с которыми и работают ROM-команды. Каждое «одноварное» устройство имеет свой 64-хбитный код, состоящий из трёх частей:

1-Wire%20-%20Unique%20code.png

Младший байт – это код семейства, к которому относится устройство, 6 следующих байт – уникальный в семействе серийный номер, ну и наконец, старший байт – это CRC, который служит для проверки правильности приёма всего кода. Так, например, на родных даллосовских (сейчас максимовских) «таблетках» часть уникального кода – а именно, 48-битный серийный номер – пишется на металле в шестнадцатиричном виде (все дружно посмотрели на свои домофонные ключи).

Рассмотрим подробнее, какие коды семейств устройств 1-Wire бывают:

Код семейства (HEX) Устройство iButton Описание
01 DS1990A, DS1990R, DS2401, DS2411 Уникальный серийный номер-ключ
02 DS1991 Мультиключ, 1152-битная защищённая EEPROM
04 DS1994, DS2404 4 КБ NV RAM + часы, таймер и будильник
05 DS2405 Одиночный адресуемый ключ
06 DS1993 4 КБ NV RAM
08 DS1992 1 КБ NV RAM
09 DS1982, DS2502 1 КБ PROM
0A DS1995 16 КБ NV RAM
0B DS1985, DS2505 16 КБ EEPROM
0C DS1996 64 КБ NV RAM
0F DS1986, DS2506 64 КБ EEPROM
10 DS1920, DS1820, DS18S20, DS18B20 Датчик температуры
12 DS2406, DS2407 1 КБ EEPROM + двухканальный адресуемый ключ
14 DS1971, DS2430A 256 бит EEPROM и 64 бита PROM
1A DS1963L 4 КБ NV RAM + счётчик циклов записи
1C DS28E04-100 4 КБ EEPROM + двухканальный адресуемый ключ
1D DS2423 4 КБ NV RAM + внешний счётчик
1F DS2409 Двухканальный адресуемый ключ с возможностью коммутации на возвратную шину
20 DS2450 Четырёхканальный АЦП
21 DS1921G, DS1921H, DS1921Z Термохронный датчик с функцией сбора данных
23 DS1973, DS2433 4 КБ EEPROM
24 DS1904, DS2415 Часы реального времени
26 DS2438 Датчик температуры, АЦП
27 DS2417 Часы реального времени с прерыванием
29 DS2408 Двунаправленный 8-разрядный порт ввода/вывода
2C DS2890 Одноканальный цифровой потенциометр
2D DS1972, DS2431 1 КБ EEPROM
30 DS2760 Датчик температуры, датчик тока, АЦП
37 DS1977 32 КБ защищённой паролем EEPROM
3A DS2413 Двухканальный адресуемый коммутатор
41 DS1922L, DS1922T, DS1923, DS2422 Термохронные и гигрохронные датчики высокого разрешения с функцией сбора данных
42 DS28EA00 Цифровой термометр с программируемым разрешением, возможностью работать в режиме подключения к последовательному каналу и программируемыми портами ввода/вывода
43 DS28EC20 20 КБ EEPROM

NV RAM – Non-Volatile Random-Access Memory (энергонезависимое ОЗУ)
PROM – Programmable Read-Only Memory (однократно программируемое ПЗУ)
EEPROM – Electrically Erasable Programmable Random-Access Memory (электрически стираемое перепрограммируемое ПЗУ)

ПРО КОМАНДУ SEARCH ROM (F0H):

По мотивам статьи Чернова Геннадия.
Если ведущий не знает серийный номер устройств, подключенных к шине, то существует возможность идентифицировать коды ROM каждого устройства – для этого необходимо использовать команду «Search ROM» [F0h]. Эта команда действует как команда «Read ROM», объединенная с командой «Match ROM».

Процесс идентификации кодов ROM ведомых устройств выглядит так:

После формирования мастером команды «Search ROM» все устройства посылают на шину значение своего младшего бита; при этом сначала в течение одного такта ведомыми посылается «прямое» значение бита, а в течение следующего такта – «обратное» (логическое НЕ, дополнение) значение этого же бита.
Тогда мастер может считать следующие последовательности:

  • «01» — если у всех ведомых устройств младший бит равен «0» (сначала они отсылают «0», потом {НЕ «0»} = «1»)
  • «10» — если у всех ведомых устройств младший бит равен «1»
  • «00» — если есть так называемый конфликт – у некоторых устройств младший бит равен «1», у остальных – «0». Тогда при передаче «прямого» значения устройства с «0» опускают линию, при передаче «обратного» — устройства с «1» также опускают линию.

Далее мастер в следующем временном слоте отсылает «0» или «1», таким образом определяя, с какими устройствами дальше будет общаться – все устройства, у которых младший бит не соответствует биту, сформированному мастером на этом этапе, перейдут в состояние ожидания и будут находиться в нём, пока не получат импульс сброса. Затем происходят аналогичные 63 цикла чтения-выбора, пока, наконец, ведущее устройство не определит код ROM одного из подчинённых устройств и не обратится к нему.
Для мастера каждая стадия выбора состоит из двух тайм-слотов чтения и одного тайм-слота записи.

Разберем работу команды «Search ROM» на примере.

Пусть на шине установлено четыре ведомых устройства со следующими значениями кодов:
устройство 1: xxxxxx10101100
устройство 2: xxxxxx01010101
устройство 3: xxxxxx10101111
устройство 4: xxxxxx10001000
для упрощения символом «x» заменены старшие биты и показаны только младшие восемь битов

Поиск младшего бита происходит следующим образом:

  1. Ведущее устройство начинает последовательность инициализации – формирует импульс сброса; ведомые устройства отвечают импульсами присутствия.
  2. Ведущее устройство формирует команду «Search ROM».
  3. Ведущее устройство читает два бита с шины. Сначала каждое ведомое устройство ответит, помещая значение первого бита, соответствующего его данным ROM. Устройства 1 и 4 поместят «0» на шину, то есть, они установят на шине низкий уровень. Устройства 2 и 3 сформируют «1», позволяя на линии оставаться в высоком уровне. Результат – «логическое И» всех устройств на линии; поэтому мастер читает 0.
    Следует отметить, что с тех пор, как ведущий послал команду «Search ROM», все ведомые устройства отвечают одновременно.
    Далее мастер читает следующий бит. Все устройства помещают на шину дополнение их первого бита. Устройства 1 и 4 сформируют «1»; устройства 2 и 3 сформируют «0». Таким образом, на шине будет состояние логического «0». Мастер снова читает «0» при формировании дополнительного кода первого информационного разряда ROM (чтение дает «00» — состояние разрядных конфликтов). Это говорит ведущему устройству, что есть устройства на шине содержащие в первом бите как «0», так и «1».
    Если бы все устройства имели «0» в этой позиции двоичного разряда, чтение дало бы результат «01«; если бы позиция двоичного разряда содержала во всех устройства «1» результат был бы «10«.
  4. Ведущее устройство решает далее анализировать устройства с нулём в младшем бите — формирует запись «0» на шину. Эта операция переводит устройства 2 и 3 (содержащие в этом разряде «1») в пассивное состояние, оставляя только устройства 1 и 4 для участия в процессе поиска.
  5. Мастер выполняет еще два чтения и получает «01». Это говорит, что все активные устройства имеют 0 в этой позиции двоичного разряда их ROM.
  6. Мастер тогда пишет 0, чтобы сохранить устройства 1 и 4 активными.
  7. Мастер выполняет два чтения и получает «00». Это снова указывает, что у устройств на линии в этом разряде есть как «1», так и «0.
  8. Мастер снова пишет 0. Это деактивирует устройство 1, оставляя устройство 4 единственным активным элементом.
  9. Следующие чтения до конца ROM не будут давать состояние разрядных конфликтов. Отсутствие разрядных конфликтов до конца цикла поиска говорит, что происходит чтение ROM только одного активного элемента. Прочитав следующий бит, мастер снова посылает этот бит, чтобы сохранить устройство активным. Как только все биты ROM устройства известны и последний бит снова послан Главным устройством, устройство готово принять функциональную команду (для обмена информацией).
  10. Ведущее устройство должно изучить данные ROM других устройств. Поэтому оно запускает следующую последовательность Поиска ROM, повторяя шаги 1-7.
  11. B самой старшей позиции двоичного разряда, где ведущее устройство писало «0» в первом проходе (шаг 8), оно теперь пишет «1». Это снимает выделение устройства 4, оставляя теперь устройство 1 активным.
  12. Как в шаге 9, следующие чтения до конца ROM не будет давать состояние разрядным конфликтам. Этим заканчивается второй Поиск ROM, где мастер считывает содержание ROM другого устройства.
  13. Ведущее устройство должно изучить данные ROM других устройств. Поэтому оно запускает следующую последовательность Поиска ROM, повторяя шаги 1-3.
  14. Во втором проходе в наивысшей степени позиция двоичного разряда, где мастер отсылал «0» в первом проходе (шаг 4), теперь он пишет «1». Это снимает выделение устройств 1 и 4, оставляя устройства 2 и 3 активными.
  15. Ведущее устройство считывает «00» — разрядный конфликт.
  16. Мастер отсылает «0». Это снимает выделение устройства 3, оставляя устройство 2 как единственное активное устройство.
  17. Как в шаге 9, следующие чтения до конца ROM не будет показывать разрядным конфликтам. Этим заканчивается третий Поиск ROM.
  18. Ведущее устройство должно изучить данные ROM других устройств. Поэтому оно запускает следующую последовательность Поиска ROM, повторяя шаги 13 — 15.
  19. В самой высокой позиции двоичного разряда, где мастер отсылал «0» (шаг 16), теперь он отсылает «1». Это снимает выделение устройства 2, оставляя устройство 3 активным.
  20. Как в шаге 17, следующие чтения до конца ROM не будут показывать разрядным конфликтам. Это заканчивает четвертый Поиск ROM.

Иными словами, в процессе поиска ROM мы строим одно или два двоичных дерева размером 64 (длина кода ROM), с корнями в виде значений младшего бита и листьями в виде значений старшего байта кода ROM.
Время, требуемое для считывания содержания одного ROM (без учёта процессорного времени мастера) = 960 мкс + (8 + 3*64) *61 мкс =13.16 мс.

Автор — Moriam

Отправка данных с Arduino на WEB-сервер GET-запросом

 Arduino  Комментарии к записи Отправка данных с Arduino на WEB-сервер GET-запросом отключены
Фев 012020
 

Описание устройства

Вычислительным мозгом устройства является платформа Arduino UNO, для связи с сетью используется Ethernet Shield, помимо этого, я установил LCD KeyPad Shield для вывода информации о состоянии различных устройств и команд, также установил все возможные датчики и реле. Continue reading »

Устройство контроля целостности кабеля связи

 Arduino  Комментарии к записи Устройство контроля целостности кабеля связи отключены
Фев 012020
 

Кабельные линии связи имеют свои особенности. Это — большая протяженность магистрали (до нескольких десятков километров), большое число проводов в кабеле, наличие в проводах, соседних с проверяемым, сигналов амплитудой до нескольких десятков вольт, сезонное изменение физических параметров линии связи.

Continue reading »

Плата TTGO T-Call

 Arduino  Комментарии к записи Плата TTGO T-Call отключены
Ноя 272019
 

На протяжении многих лет компания LilyGo выпускала платы TTGO, обычно основанные на базе Espressif ESP8266 или ESP32. Вот еще один вариант, который может быть полезен, если конечно в вашей стране еще не отказались от сотовой сети 2G: TTGO T-Call. Continue reading »