Считать данные с DS2406
- Войдите на сайт для отправки комментариев
Ср, 15/01/2014 - 22:42
Здравствуйте. Помогите пожалуйста разобраться с двухканальным 1-wire ключом DS2406P
Даташит взял тут http://pdfserv.maximintegrated.com/en/ds/DS2406.pdf.
Пробовал пользоваться библиотекой http://github.com/dustin/arduino-2406. Но среди ее стандартных функций не разобрался как настроить порт PIO_A на ввод и считать его состояние. В примерах есть только запись в память
В программировании еще новичок. Вот набросал код с использованием библиотеки OneWire
#include <OneWire.h>
OneWire ds(9);
uint8_t address[8] = {0x12, 0x2E, 0xED, 0x3D, 0, 0, 0, 0xC7};
uint8_t CHANNEL_ACCESS = 0xF5;
uint8_t CHANNEL_CONTROL_BYTE = 01000100; //ALR=0;IM=1;TOG=0;IC=0;CHS1=0;CHS0=1;CRC1=0;CRC0=0
uint8_t buffer;
void setup(void)
{
Serial.begin(9600);
}
void loop(void)
{
ds.reset();
ds.select(address);
ds.write(CHANNEL_ACCESS,1);
ds.write(CHANNEL_CONTROL_BYTE,1);
ds.write(0xFF,1);
ds.write(CHANNEL_CONTROL_BYTE,1);
ds.write(0xFF,1);
buffer = ds.read();
ds.reset();
Serial.println(buffer);
delay(2000);
}
Но в мониторе порта постоянно показывает 255 (11111111). Чего по идее (согласно даташиту) не должно быть.
Помогите разобраться пожалуйста. Спасибо.
В свое время руки не дошли научиться читать, вот списочек может вам поможет.
Спасибо за наводку))) А Вы это все из даташита вычитали? Я просто видимо не нашел или не понял как именно эти коды выделить из тех таблиц. Буду пробовать
Romosyto, у вас получилось разобраться как работать с ds2406?
Да, получилось) Код дома на компе. Вечером отпишусь...
Ок. Жду. Спасибо.
После безуспешных поисков на форумах и в инете, вот что удалось набыдлокодить)) :
#include <OneWire.h> OneWire ds(9); //У меня шина на входе 9 uint8_t address[8] = {0x12, 0x2E, 0xED, 0x3D, 0, 0, 0, 0xC7}; //Адрес устройства (заменить на ваш) uint8_t CHANNEL_ACCESS = 0xF5; //1 byte uint8_t CHANNEL_CONTROL_BYTE = 0x44; //ALR=0;IM=1;TOG=0;IC=0;CHS1=0;CHS0=1;CRC1=0;CRC0=0 (NO CRC) uint8_t data; int alarm = 0; void setup(void) { Serial.begin(9600); } void loop(void) { ds.reset(); ds.select(address); ds.write(CHANNEL_ACCESS); ds.write(CHANNEL_CONTROL_BYTE); ds.write(0xFF); data = ds.read(); ds.reset(); Serial.print("DATA BIN = "); Serial.println(data, BIN); Serial.print("STATUS = "); if (byte bitRead(data,2) == 1 && alarm < 5) { alarm +=1; Serial.println("WARNING!!!"); } else if (byte bitRead(data,2) == 1 && alarm >= 5) { alarm = 5; Serial.println("ALARM"); } else { Serial.println("OK"); } if (byte bitRead(data,2) == 0 && alarm > 0) { alarm = 0; } Serial.println("------------------------"); delay(3000); }Пояснения к коду:
У меня микросхема в двухканальном исполнении и мне нужно получить состояние входа PIO A.
Для того чтобы получить состояние портов необходимо обратиться либо к памяти устройства (до этого у меня мозгов не хватило) либо послать устройству сигнал CHANNEL ACCESS 0xF5 а затем так называемый CHANNEL CONTROL BYTE, в котором в каждом бите зашифровано, что Вы хотите получить от устройства.
У меня это значение 0x44;
А это расщифровка каждого байта по даташиту
ALR=0;IM=1;TOG=0;IC=0;CHS1=0;CHS0=1;CRC1=0;CRC0=0 (NO CRC)
CHS1=0 и CHS0=1 формируют запрос к PIO A;
IC=0 устанавливает асинхронный режим передачи. Так как у меня одноканальное чтение, то ставим 0
IM=1 и TOG=0 устанавливают режим чтения из выбранного порта
CRC1=0 и CRC0=0 отключают режим формирования CRC (Опытным путем выяснил, что при простом чтении состояния, CRC не формируется, поэтому установил нули)
ALR=0 - какая-то хрень с защелкой. Толком не удалось разобраться (вроде вычитал, что надо поставить ноль)
После отправки CHANNEL CONTROL BYTE к устройству, оно передает вам в ответ CHANNEL INFO BYTE, в каждом бите которого зашифровано состояние устройства. По даташиту меня интересовал байт 2, который передает состояние PIO A (для PIO B это байт 3).
Далее чтобы искючить ложные срабатывания (а такое опытным путем установлено, что бывает), я подряд 5 раз читаю состояние PIO A и если они подряд идут сработавшими - то вывожу "АВАРИЯ".
Код может и не изящен, но чем богаты так сказать)) Получится разобраться с CRC и памятью - поделитесь опытом)
Большое спасибо. Попробую. Если что-то додумаю обязательно поделюсь.
#include <OneWire.h> OneWire ds(13); uint8_t ds1[8] = {0x12, 0xF3, 0xF7, 0xA0, 0, 0, 0, 0xF4}; #define CHANNEL_ACCESS 0xF5; #define CHANNEL_CONTROL_BYTE 0x45; void setup() { Serial.begin(9600); } void loop() { uint8_t buf[7]; ds.reset(); ds.select(ds1); buf[0] = CHANNEL_ACCESS; buf[1] = CHANNEL_CONTROL_BYTE; buf[2] = 0xFF; ds.write_bytes(buf, 3); ds.read_bytes(buf+3, 4); // 3 cmd bytes, 1 data byte, 1 0x00, 2 CRC16 ds.reset(); if (!OneWire::check_crc16(buf, 5, &buf[5])) { //если контрольная сумма не верна - возврат return; } Serial.print(" DS2406 data = "); //вывод CHANNEL INFO BYTE Serial.println(buf[3], BIN); }вот что у меня получилось.
И как? работает?
Можно по подробнее про CRC?
Про вот эту строчку "// 3 cmd bytes, 1 data byte, 1 0x00, 2 CRC16" ?
Жаль что вопросы Romosyto за 8 лет так и не отвечены...
Приехала ко мне эта самая ds2406. После поиска и чтения даташита вижу что нужен пример работы с этой штукой.
Дело в том что автор библиотекой http://github.com/dustin/arduino-2406 явно не докурил все возможности чипа.
Мне пока интересна запись в устройство. Т.е. вывод сигнала на его порт
Код примера БлинкБезДелеяDS2406 на порту А
#include <OneWire.h> #define ONE_WIRE_PIN A4 OneWire myWire(ONE_WIRE_PIN); uint8_t CHANNEL_ACCESS = 0xF5; #define CHANNEL_CONTROL_BYTE_1_ALR 0x80 //ALR=0 not changed if reset #define CHANNEL_CONTROL_BYTE_1_IM 0x40 //IM=1 - чтение, при чередовании чтение первое #define CHANNEL_CONTROL_BYTE_1_TOG 0x20 //TOG=1 - чередование чтения и записи TOG=0 Write all bits to the selected channel #define CHANNEL_CONTROL_BYTE_1_IC 0x10 //IC=0 - asynchronous mode #define CHANNEL_CONTROL_BYTE_1_CHS1 0x08 //CHS1=1 CHS0=0 channel B only #define CHANNEL_CONTROL_BYTE_1_CHS0 0x04 //CHS1=0 CHS0=1 channel A only #define CHANNEL_CONTROL_BYTE_1_CRC1 0x02 // CRC1=0 CRC0=0 no CRC, 01 -CRC after every byte #define CHANNEL_CONTROL_BYTE_1_CRC0 0x01 // 10 - CRC after 8 bytes 11-CRC after 32 bytes uint8_t CHANNEL_CONTROL_BYTE = CHANNEL_CONTROL_BYTE_1_CHS0; //канал А на вывод данных без CRC uint8_t cib; void setup() { // put your setup code here, to run once: myWire.reset(); // myWire.select(addrArray); myWire.skip(); myWire.write(CHANNEL_ACCESS,1); myWire.write(CHANNEL_CONTROL_BYTE,1); myWire.write(0xFF,1); cib=myWire.read(); } void loop() { // put your main code here, to run repeatedly: uint8_t t; static uint8_t t0; static uint8_t b; t=millis(); if((uint8_t)(t-t0)>=200) { t0=t; myWire.write_bit(b); b^=1; } }Самое интересное - стр.47
Быстрый вывод одного бита прямо в пор. Как видим его можно повторять до сконания века или ресета шины. Очевидно вывод защищен от помех только везением, зато очень быстрый и простой. Если вместо одного бита выводить сразу байт, то будет воспринято как последовательные 8 бит. Можно задействовать оба порт, тогда передаваемые биты поочередно будут выводится то в один, то в другой. Можно даже синхронизировать процесс.
Ввод данных аналогичным путем так же возможен.
Похоже такой скоростной вывод позволит делать занятные вещи на 1Wire. Например поцепить серву. Или эмулировать I2C и поцепить что то типа 1604.
В 2413 похоже такого нет.
Битовые операции OneWire не во всех описаниях есть, похоже в старых версиях их воще не было.