Непонятки с DS2408 (8-канальный I/O по шине 1-Wire)
- Войдите на сайт для отправки комментариев
Пнд, 16/02/2015 - 01:21
Как-то мало информации в сети по этим микросхемкам :(
Собственно ардуинка ее видит, адрес определяет, но пинами дрыгать отказывается.
Даташит: http://datasheets.maximintegrated.com/en/ds/DS2408.pdf
Подключаю вот по такой схеме: http://www.homautomation.org/wp-content/uploads/2015/01/1wireDS2408Connected_sch%C3%A9ma.png
К выводам P0 и P7 через резисторы 330 Ом подключены по светодиоду, вторым концом на +5В.
Код взят отсюда: https://github.com/vdemay/DS2408/blob/master/Arduino/lightLed/lightLed.ino
только вместо кнопки просто пытаюсь включить/выключить LED:
#include <WProgram.h>
#include <DS2408.h>
#include <OneWire.h>
#include <string.h>
#include <stdio.h>
#define ONE_WIRE_BUS_PORT 8
DS2408 ds(ONE_WIRE_BUS_PORT);
Devices devices;
uint8_t device_count;
void setup(void) {
device_count = ds.find(&devices);
print_devices(&devices, device_count);
}
void loop(void) {
for(int index=0; index < device_count; index++) {
uint8_t readDevice = ds.get_state(devices[index]);
ds.set_state(devices[index], ~0b10000000);
delay(1000);
ds.set_state(devices[index], ~0b00000001);
delay(1000);
}
}
}
/* --------------- PRINT HELPERS --------------- */
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();
}
}
По идее, светодиоды должны перемигиваться, но они вообще не не светятся.
P.S. Подключение / отключение RSTZ ни на что не влияет.
попробуйте перевернуть светодиоды.
Теоретически все нормально. Разве что я бы rstz через резистор подключил, поскольку он может быть выходом.
А у меня пока до них руки не дошли, лежат до поры до времени. 2408 и 2480.
Измеряю вольтметром - на этих пинах 0.02 В.
Скажите, а почему второй вывод светодиода подключаете к +5В? Разве не на GND надо цеплять?
надо к vcc. выход такой. вторая строчка
По даташиту это пины типа Open Drain, поэтому к +5 (тут хорошо описано что это такое: http://easyelectronics.ru/osnovy-na-palcax-chast-4.html),т.е. если они работают как выход, то коммутируют минус, как и ULN2003.
Я с DS2413 работал (насколько я понимаю тоже самое но на 2 пина, а не на 8). Все работает.
Только учтите, что они землю включают, т.е. на выходе два состояния "земля" и "обрыв".
Вот скетчик нашел которым проверял:
#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, bool newline=0) { for (uint8_t i = 0; i < count; i++) { Serial.print(addr[i]>>4, HEX); Serial.print(addr[i]&0x0f, HEX); Serial.print(" "); } if (newline) { Serial.println(); } } 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 readstate(void) { /* Read */ long qwe = micros(); uint8_t state = read(); qwe = micros() - qwe; Serial.println(qwe); if (state == -1) Serial.println(F("Failed reading the DS2413")); else Serial.println(state, BIN); } void loop(void) { /* Write */ bool ok = false; ok = write(0x3); if (!ok) Serial.println(F("Wire failed")); delay(500); readstate(); delay(500); ok = write(0x2); if (!ok) Serial.println(F("Wire failed")); delay(500); readstate(); delay(500); ok = write(0x0); if (!ok) Serial.println(F("Wire failed")); delay(500); readstate(); delay(500); }проверку у меня проходит и в serial выводит уникальный ID, т.е. микруха на линии сидит корректно. А вот пинами рулитть отказывается.
Ну у меня мой скетч диодами мигал.
з.ы. Ну и ещё, учтите, что там допустимый ток достаточно мал, так что диодами мигать ещё можно, а вот, например, реле включать/выключать на прямую уже не выйдет, надо схемку городить.
на DS2413 заработало с первой попытки. Эх, пойду паучкам лапки пришивать...
после замены DS2408 на такую же все заработало. Походу, был полудохлый чип. :)