DS2408. Читать научились, а писать еще нет.
- Войдите на сайт для отправки комментариев
Втр, 12/11/2013 - 01:12
Доброго времени суток, дорогие товарищи. Подскажите пожалуста как управлять этой заразой. Состояние входов\выходов прочитать могу, а вот как управлять светодиодами, к примеру, не могу раму собрать. Подскажите хотя-бы в какую сторону копать.
Судя по даташиту нужно записать в определённый регистр один байт. Но как это сделать ума не приложу.
Заранее благодарен.
https://github.com/search?q=DS2408
Если в даташите не понятно то глянь библиотеку которую писали еще под старую версию IDE Arduino.
Спасибо. Уже смотрю... Но что-то всё равно светодиоды не моргают, морды такие.
Решено.
Судя по всему какя-то ошибка(несоответствие) в файле примера. Удалил одну строку с условием и светодиоды заморгали.
Всем спасибо за внимание.
ну а написать остальным чего и как?
Прошу прощения. Как-то не подумал.
#include <WProgram.h> #include <DS2408.h> #include <OneWire.h> #include <string.h> #include <stdio.h> #define DEVICE_BUS_PORT 10 DS2408 ds(DEVICE_BUS_PORT); Device led_device = {0x29, 0xF5, 0x22, 0x7, 0x00, 0x00, 0x00, 0xBD}; Device reader_device = {0x29, 0xF5, 0x22, 0x7, 0x00, 0x00, 0x00, 0x47}; Devices devices; uint8_t device_count; static FILE uartout = {0} ; static int uart_putchar (char c, FILE *stream) { Serial.write(c) ; return 0 ; } void setup_stdout() { fdev_setup_stream (&uartout, uart_putchar, NULL, _FDEV_SETUP_WRITE); stdout = &uartout ; } #ifdef CXA_PURE_VIRTUAL_FIX extern "C" void __cxa_pure_virtual(void); void __cxa_pure_virtual(void) { while(1); } #endif void print_byte(uint8_t data); void print_address(byte* address); void print_devices(Devices* devices, uint8_t device_count); void setup_devices(Devices* devices, uint8_t device_count); void display_mode(Device device); void display_activity(Device device); void display_state(Device device); void setup(void) { Serial.begin(9600); setup_stdout(); Serial.println("Welcome2"); device_count = ds.find(&devices); print_devices(&devices, device_count); setup_devices(&devices, device_count); } void loop(void) { uint8_t state = 0; bool left = 1; for(int index=0; index<device_count; index++) { print_address(devices[index]); // if(devices[index][7] == 0xBD) { // Тут по идее идёт проверка на то что устройство дествительно является свитчем. ds.set_state(devices[index], state); for(int index1=0; index1<100; index1++) { if(state == 0xFF || state == 0) left = !left; if(left) state = (state<<1)+1; else state = state>>1; ds.set_state(state, true); Serial.print("State: "); Serial.println(state); delay(100); } // } display_mode(devices[index]); display_activity(devices[index]); display_state(devices[index]); Serial.println(); } } void setup_devices(Devices* devices, uint8_t device_count) { for(int index=0; index < device_count; index++) { ds.set_mode((*devices)[index], RESET_PIN_MODE(STROBE_MODE)); } } void display_mode(Device device) { Serial.print(" MODE="); print_byte(ds.get_mode(device)); } void display_activity(Device device) { Serial.print(" ACTIVTY="); print_byte(ds.get_activity(device)); } void display_state(Device device) { Serial.print(" STATE="); print_byte(ds.get_state(device)); } void print_byte(uint8_t data) { for(int index=0; index<8; index++) { Serial.print(data & 1, BIN); data = data >> 1; } } void print_address(byte* address) { Serial.print("["); for(int index = 0; index < sizeof(Device); index++) { Serial.print(address[index], HEX); if(index < sizeof(Device)-1) Serial.print(" "); } Serial.print("] "); } void print_devices(Devices* devices, uint8_t device_count) { Serial.print("Found "); Serial.print(device_count , HEX); Serial.println(" devices."); for(int index=0; index < device_count; index++) { Serial.print(index+1, HEX); Serial.print(". "); print_address((*devices)[index]); Serial.println(); } }Проблемную строку пометил коментарием.
А вобще для того что-бы светодиоды запигали достаточно вот этого:
#include <DS2408.h> #include <OneWire.h> #define DEVICE_BUS_PORT 10 DS2408 ds(DEVICE_BUS_PORT); Devices devices; uint8_t device_count; void setup(void) { Serial.begin(9600); device_count = ds.find(&devices); } void loop(void) { uint8_t state = 0; bool left = 1; for(int index=0; index<device_count; index++) { // if(devices[index][7] == 0xBD) { // Тут по идее идёт проверка на то что устройство дествительно является свитчем. ds.set_state(devices[index], state); for(int index1=0; index1<100; index1++) { if(state == 0xFF || state == 0) left = !left; if(left) state = (state<<1)+1; else state = state>>1; ds.set_state(state, true); delay(100); } // } } }GreenDer ,
у вас на шине подключенны 2 штуки ds2408 судя по ID устройств, на одной "висят" светодиоды, на другой физические кнопки, я правильно понимаю?
Нет. на шине два ds2408 со светодиодами. Скетч поочередно переключает светодиоды на них. Кнопок нет.
Добрый день!
Сложно сказать - переменная devices, видимо, описана в DS2408.h, и поэтому из скеча ен понятна её структура. Ну проверить-то просто: напишите в 30-й строке (2-й скеч), что-нибудь типа:
Serial.Println(devices[index][7]);
И посмотрите, что она вам выводит: 0xBD или нет :).
Да уже разобрался, спасибо.
Это явная ошибка автора скетча. index[7] это последний байт имени конкретного устройства. Т.к у меня все подключенные устройства имеют другие имена то проверка условия естественно заканчивалась false.
Видимо автор хотел сделать проверку на принадлежность устроства к семейству DS2408, но перепутал байты. Нужно было первый байт проверять.
Хочу реализовать удалённое управление четырьмя релюшками. Думал купить DS2408. Скажите, какие плюсы у неё? Не легче ли использовать вместо неё atmega328? atmega328 стоит 30р. Ардуинка на atmega328 стоит 80р. А DS2408 стоит от 260р. Что ей можно сделать, чего нельзя реализовать на обычной ардуино?
Да всё можно реализовать обоими способами. Основная фича DS2408 - это то, что в неё уже вшит протокол 1-wire. Т.е. вам вообще не надо париться с кодом на клиентской (исполняющей) стороне. Причём реализован он хардверно, с правильными таймингами. Т.е. танцы с бубном будут сведены к минимуму. Или даже полностью исключены, если и мастер хардверный использовать. Плюс почти никакой обвязки не надо. Но это всё актуально, если у вас большие расстояния. А если 4 релюшки в одном месте (иначе зачем DS2408?), да на рассоянии в пол-метра, то смысл, конечно не очевиден. В этом случае я б в сторону I2C какого-нибудь посмотрел...
Если же расстояния большие (несколько метров и дальше), то лучше бы именно хардверные 1-Wire устройства - больше вероятность, что заработает :).
Ясно. Расстояние около 15метров.
У неё 8 каналов. Есть возможность сконфигурировать четыре как вход, и четыре как выход? Нужно подавать питание на релюхи, если релюха сработала, то при запуске устройства есть подтверждающий сигнал, когда устройство запустилость и нормально функционирует сухой контакт этого устройста размыкается. Тоесть нужно на некоторые подавать, а с некоторых считывать. Считывать нужно два состояния, либо Есть сигнал, Либо нет.
У неё 8 IO каналов, каждый из которых может работать как угодно и независимо друг от друга. Т.е. 4 входа/4 выхода тоже можно. При этом она как таковая не конфигурируется специально. Режим работы зависит от схемы включения. А с точки зрения софта: там 2 регистра. В один регистр вы записываете состояния, которые хотите назначить соответствующим ногам (для Outputs), а из второго считываете реальное состояние ног в данный момент (режим Input). Там всё просто.
Я в таком режиме работал с DS2413 - это двухканальный ключ. Но работает по-аналогии.
По поводу 15 м - I2C тогда не вариант. Тогда либо какой-нибудь RS485 использовать, либо вот как раз 1-wire. Для 1-wire 15 метров - это фигня.
можете поделиться примером, когда "В один регистр вы записываете состояния, которые хотите назначить соответствующим ногам (для Outputs)"?
Надо записывать все 8 состояний, или только одно, которое надо изменить?
Ни в одном из примеров в сети не удалось найти пример использования функции set_register, везде используют только set_state.
И в примере из поста #5 за что отвечают MODE, ACTIVTY, STATE,? В самой библиотеке комментарии настолько скудные, что нифига непонятно.
Я работал только с DS2413. Если поможет - вечером приведу пример. Делал всё по Datasheet.
думаю, поможет. Они во многом схожи.
Один в один. Разница только в количестве пинов.
Прошу прощения, никак не получается добраться до компьютера. Если подождёте, смогу ответить в четверг.
Я ещё жду :)
Я ещё жду :)
Фигасе терпеливый какой!
где был?
ds2413 корявенький код записи
#include <OneWire.h> #define DS2413_ONEWIRE_PIN (8) #define DS2413_FAMILY_ID 0x3A #define DS2413_ACCESS_READ 0xF5 #define DS2413_ACCESS_WRITE 0x5A #define DS2413_ACK_SUCCESS 0xAA #define DS2413_ACK_ERROR 0xFF OneWire oneWire(DS2413_ONEWIRE_PIN); uint8_t address[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; void printBytes(uint8_t* addr, uint8_t count) { for (uint8_t i = 0; i < count; i++) { Serial.print(addr[i]>>4, HEX); Serial.print(addr[i]&0x0f, HEX); Serial.print(" "); } } byte read(void) { bool ok = false; uint8_t results; oneWire.reset(); oneWire.select(address); oneWire.write(DS2413_ACCESS_READ); results = oneWire.read(); /* Get the register results */ ok = (!results & 0x0F) == (results >> 4); /* Compare nibbles */ results &= 0x0F; /* Clear inverted values */ oneWire.reset(); // return ok ? results : -1; return results; } bool write(uint8_t state) { uint8_t ack = 0; /* Top six bits must '1' */ state |= 0xFC; oneWire.reset(); oneWire.select(address); oneWire.write(DS2413_ACCESS_WRITE); oneWire.write(state); oneWire.write(~state); /* Invert data and resend */ ack = oneWire.read(); /* 0xAA=success, 0xFF=failure */ if (ack == DS2413_ACK_SUCCESS) { oneWire.read(); /* Read the status byte */ } oneWire.reset(); return (ack == DS2413_ACK_SUCCESS ? true : false); } void setup(void) { Serial.begin(9600); Serial.println(F("Looking for a DS2413 on the bus")); /* Try to find a device on the bus */ oneWire.reset_search(); delay(250); if (!oneWire.search(address)) { printBytes(address, 8); Serial.println(F("No device found on the bus!")); oneWire.reset_search(); while(1); } /* Check the CRC in the device address */ if (OneWire::crc8(address, 7) != address[7]) { Serial.println(F("Invalid CRC!")); while(1); } /* Make sure we have a DS2413 */ if (address[0] != DS2413_FAMILY_ID) { printBytes(address, 8); Serial.println(F(" is not a DS2413!")); while(1); } Serial.print(F("Found a DS2413: ")); printBytes(address, 8); Serial.println(F("")); } void loop(void) { bool ok = false; ok = write(B00000001); if (!ok) Serial.println(F("Wire failed")); delay(1000); ok = write(B00000010); if (!ok) Serial.println(F("Wire failed")); delay(1000); }чтения
#include <OneWire.h> #define DS2413_ONEWIRE_PIN (8) #define DS2413_FAMILY_ID 0x3A #define DS2413_ACCESS_READ 0xF5 #define DS2413_ACCESS_WRITE 0x5A #define DS2413_ACK_SUCCESS 0xAA #define DS2413_ACK_ERROR 0xFF OneWire oneWire(DS2413_ONEWIRE_PIN); uint8_t address[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; void printBytes(uint8_t* addr, uint8_t count) { for (uint8_t i = 0; i < count; i++) { Serial.print(addr[i]>>4, HEX); Serial.print(addr[i]&0x0f, HEX); Serial.print(" "); } } byte read(void) { bool ok = false; uint8_t results; oneWire.reset(); oneWire.select(address); oneWire.write(DS2413_ACCESS_READ); results = oneWire.read(); /* Get the register results */ ok = (!results & 0x0F) == (results >> 4); /* Compare nibbles */ results &= 0x0F; /* Clear inverted values */ oneWire.reset(); // return ok ? results : -1; return results; } bool write(uint8_t state) { uint8_t ack = 0; /* Top six bits must '1' */ state |= 0xFC; oneWire.reset(); oneWire.select(address); oneWire.write(DS2413_ACCESS_WRITE); oneWire.write(state); oneWire.write(~state); /* Invert data and resend */ ack = oneWire.read(); /* 0xAA=success, 0xFF=failure */ if (ack == DS2413_ACK_SUCCESS) { oneWire.read(); /* Read the status byte */ } oneWire.reset(); return (ack == DS2413_ACK_SUCCESS ? true : false); } void setup(void) { Serial.begin(9600); Serial.println(F("Looking for a DS2413 on the bus")); /* Try to find a device on the bus */ oneWire.reset_search(); delay(250); if (!oneWire.search(address)) { printBytes(address, 8); Serial.println(F("No device found on the bus!")); oneWire.reset_search(); while(1); } /* Check the CRC in the device address */ if (OneWire::crc8(address, 7) != address[7]) { Serial.println(F("Invalid CRC!")); while(1); } /* Make sure we have a DS2413 */ if (address[0] != DS2413_FAMILY_ID) { printBytes(address, 8); Serial.println(F(" is not a DS2413!")); while(1); } Serial.print(F("Found a DS2413: ")); printBytes(address, 8); Serial.println(F("")); } void loop(void) { uint8_t state = read(); const int IOA = 0x1; const int IOB = 0x5; // проблема с отображением информации if (state & IOA) { Serial.println("A OFF"); } else { Serial.println("A ON"); } if (state & IOB) { Serial.println("B OFF"); } else { Serial.println("B ON"); } Serial.println(state, BIN); Serial.println(); delay(1000); /* Read */ /* uint8_t state = read(); if (state == -1) Serial.println(F("Failed reading the DS2413")); else Serial.println(state, BIN); */ }