DS2408. Читать научились, а писать еще нет.
- Войдите на сайт для отправки комментариев
Втр, 12/11/2013 - 01:12
Доброго времени суток, дорогие товарищи. Подскажите пожалуста как управлять этой заразой. Состояние входов\выходов прочитать могу, а вот как управлять светодиодами, к примеру, не могу раму собрать. Подскажите хотя-бы в какую сторону копать.
Судя по даташиту нужно записать в определённый регистр один байт. Но как это сделать ума не приложу.
Заранее благодарен.
https://github.com/search?q=DS2408
Если в даташите не понятно то глянь библиотеку которую писали еще под старую версию IDE Arduino.
Спасибо. Уже смотрю... Но что-то всё равно светодиоды не моргают, морды такие.
Решено.
Судя по всему какя-то ошибка(несоответствие) в файле примера. Удалил одну строку с условием и светодиоды заморгали.
Всем спасибо за внимание.
ну а написать остальным чего и как?
Прошу прощения. Как-то не подумал.
001
#include <WProgram.h>
002
#include <DS2408.h>
003
#include <OneWire.h>
004
#include <string.h>
005
006
#include <stdio.h>
007
008
009
#define DEVICE_BUS_PORT 10
010
011
DS2408 ds(DEVICE_BUS_PORT);
012
013
Device led_device = {0x29, 0xF5, 0x22, 0x7, 0x00, 0x00, 0x00, 0xBD};
014
Device reader_device = {0x29, 0xF5, 0x22, 0x7, 0x00, 0x00, 0x00, 0x47};
015
016
017
Devices devices;
018
uint8_t device_count;
019
020
static
FILE uartout = {0} ;
021
static
int
uart_putchar (
char
c, FILE *stream) {
022
Serial
.write(c) ;
023
return
0 ;
024
}
025
void
setup_stdout() {
026
fdev_setup_stream (&uartout, uart_putchar, NULL, _FDEV_SETUP_WRITE);
027
stdout = &uartout ;
028
}
029
030
#ifdef CXA_PURE_VIRTUAL_FIX
031
extern
"C"
void
__cxa_pure_virtual(
void
);
032
void
__cxa_pure_virtual(
void
) {
while
(1); }
033
#endif
034
035
void
print_byte(uint8_t data);
036
void
print_address(
byte
* address);
037
void
print_devices(Devices* devices, uint8_t device_count);
038
void
setup_devices(Devices* devices, uint8_t device_count);
039
void
display_mode(Device device);
040
void
display_activity(Device device);
041
void
display_state(Device device);
042
043
void
setup
(
void
) {
044
Serial
.begin(9600);
045
setup_stdout();
046
047
Serial
.println(
"Welcome2"
);
048
049
device_count = ds.find(&devices);
050
print_devices(&devices, device_count);
051
setup_devices(&devices, device_count);
052
}
053
054
055
void
loop
(
void
) {
056
uint8_t state = 0;
057
bool
left = 1;
058
for
(
int
index=0; index<device_count; index++) {
059
print_address(devices[index]);
060
061
// if(devices[index][7] == 0xBD) { // Тут по идее идёт проверка на то что устройство дествительно является свитчем.
062
ds.set_state(devices[index], state);
063
for
(
int
index1=0; index1<100; index1++) {
064
if
(state == 0xFF || state == 0)
065
left = !left;
066
if
(left)
067
state = (state<<1)+1;
068
else
069
state = state>>1;
070
ds.set_state(state,
true
);
071
Serial
.print(
"State: "
);
Serial
.println(state);
072
delay(100);
073
}
074
// }
075
076
display_mode(devices[index]);
077
display_activity(devices[index]);
078
display_state(devices[index]);
079
Serial
.println();
080
}
081
}
082
083
void
setup_devices(Devices* devices, uint8_t device_count) {
084
for
(
int
index=0; index < device_count; index++) {
085
ds.set_mode((*devices)[index], RESET_PIN_MODE(STROBE_MODE));
086
}
087
}
088
089
void
display_mode(Device device) {
090
Serial
.print(
" MODE="
);
091
print_byte(ds.get_mode(device));
092
}
093
void
display_activity(Device device) {
094
Serial
.print(
" ACTIVTY="
);
095
print_byte(ds.get_activity(device));
096
}
097
void
display_state(Device device) {
098
Serial
.print(
" STATE="
);
099
print_byte(ds.get_state(device));
100
}
101
102
void
print_byte(uint8_t data) {
103
for
(
int
index=0; index<8; index++) {
104
Serial
.print(data & 1, BIN);
105
data = data >> 1;
106
}
107
}
108
void
print_address(
byte
* address) {
109
Serial
.print(
"["
);
110
for
(
int
index = 0; index <
sizeof
(Device); index++) {
111
Serial
.print(address[index], HEX);
112
if
(index <
sizeof
(Device)-1)
113
Serial
.print(
" "
);
114
}
115
Serial
.print(
"] "
);
116
}
117
118
void
print_devices(Devices* devices, uint8_t device_count) {
119
Serial
.print(
"Found "
);
120
Serial
.print(device_count , HEX);
121
Serial
.println(
" devices."
);
122
123
for
(
int
index=0; index < device_count; index++) {
124
Serial
.print(index+1, HEX);
125
Serial
.print(
". "
);
126
print_address((*devices)[index]);
127
Serial
.println();
128
}
129
}
Проблемную строку пометил коментарием.
А вобще для того что-бы светодиоды запигали достаточно вот этого:
01
#include <DS2408.h>
02
#include <OneWire.h>
03
04
05
06
07
08
#define DEVICE_BUS_PORT 10
09
10
DS2408 ds(DEVICE_BUS_PORT);
11
12
13
Devices devices;
14
uint8_t device_count;
15
16
17
void
setup
(
void
)
18
{
19
Serial
.begin(9600);
20
device_count = ds.find(&devices);
21
22
}
23
24
25
void
loop
(
void
)
26
{
27
uint8_t state = 0;
28
bool
left = 1;
29
for
(
int
index=0; index<device_count; index++) {
30
31
// if(devices[index][7] == 0xBD) { // Тут по идее идёт проверка на то что устройство дествительно является свитчем.
32
ds.set_state(devices[index], state);
33
for
(
int
index1=0; index1<100; index1++) {
34
if
(state == 0xFF || state == 0)
35
left = !left;
36
if
(left)
37
state = (state<<1)+1;
38
else
39
state = state>>1;
40
ds.set_state(state,
true
);
41
delay(100);
42
}
43
// }
44
45
46
}
47
}
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 корявенький код записи
001
#include <OneWire.h>
002
003
#define DS2413_ONEWIRE_PIN (8)
004
005
#define DS2413_FAMILY_ID 0x3A
006
#define DS2413_ACCESS_READ 0xF5
007
#define DS2413_ACCESS_WRITE 0x5A
008
#define DS2413_ACK_SUCCESS 0xAA
009
#define DS2413_ACK_ERROR 0xFF
010
011
OneWire oneWire(DS2413_ONEWIRE_PIN);
012
uint8_t address[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
013
014
void
printBytes(uint8_t* addr, uint8_t count)
015
{
016
for
(uint8_t i = 0; i < count; i++)
017
{
018
Serial
.print(addr[i]>>4, HEX);
019
Serial
.print(addr[i]&0x0f, HEX);
020
Serial
.print(
" "
);
021
}
022
023
}
024
025
byte
read(
void
)
026
{
027
bool
ok =
false
;
028
uint8_t results;
029
030
oneWire.reset();
031
oneWire.select(address);
032
oneWire.write(DS2413_ACCESS_READ);
033
034
results = oneWire.read();
/* Get the register results */
035
ok = (!results & 0x0F) == (results >> 4);
/* Compare nibbles */
036
results &= 0x0F;
/* Clear inverted values */
037
038
oneWire.reset();
039
040
// return ok ? results : -1;
041
return
results;
042
}
043
044
bool
write(uint8_t state)
045
{
046
uint8_t ack = 0;
047
048
/* Top six bits must '1' */
049
state |= 0xFC;
050
051
oneWire.reset();
052
oneWire.select(address);
053
oneWire.write(DS2413_ACCESS_WRITE);
054
oneWire.write(state);
055
oneWire.write(~state);
/* Invert data and resend */
056
ack = oneWire.read();
/* 0xAA=success, 0xFF=failure */
057
if
(ack == DS2413_ACK_SUCCESS)
058
{
059
oneWire.read();
/* Read the status byte */
060
}
061
oneWire.reset();
062
063
return
(ack == DS2413_ACK_SUCCESS ?
true
:
false
);
064
}
065
066
void
setup
(
void
)
067
{
068
Serial
.begin(9600);
069
070
Serial
.println(F(
"Looking for a DS2413 on the bus"
));
071
072
/* Try to find a device on the bus */
073
oneWire.reset_search();
074
delay(250);
075
if
(!oneWire.search(address))
076
{
077
printBytes(address, 8);
078
Serial
.println(F(
"No device found on the bus!"
));
079
oneWire.reset_search();
080
while
(1);
081
}
082
083
/* Check the CRC in the device address */
084
if
(OneWire::crc8(address, 7) != address[7])
085
{
086
Serial
.println(F(
"Invalid CRC!"
));
087
while
(1);
088
}
089
090
/* Make sure we have a DS2413 */
091
if
(address[0] != DS2413_FAMILY_ID)
092
{
093
printBytes(address, 8);
094
Serial
.println(F(
" is not a DS2413!"
));
095
while
(1);
096
}
097
098
Serial
.print(F(
"Found a DS2413: "
));
099
printBytes(address, 8);
100
Serial
.println(F(
""
));
101
}
102
103
void
loop
(
void
)
104
{
105
bool
ok =
false
;
106
ok = write(B00000001);
107
if
(!ok)
Serial
.println(F(
"Wire failed"
));
108
delay(1000);
109
ok = write(B00000010);
110
if
(!ok)
Serial
.println(F(
"Wire failed"
));
111
delay(1000);
112
}
чтения
001
#include <OneWire.h>
002
003
#define DS2413_ONEWIRE_PIN (8)
004
005
#define DS2413_FAMILY_ID 0x3A
006
#define DS2413_ACCESS_READ 0xF5
007
#define DS2413_ACCESS_WRITE 0x5A
008
#define DS2413_ACK_SUCCESS 0xAA
009
#define DS2413_ACK_ERROR 0xFF
010
011
OneWire oneWire(DS2413_ONEWIRE_PIN);
012
uint8_t address[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
013
014
void
printBytes(uint8_t* addr, uint8_t count)
015
{
016
for
(uint8_t i = 0; i < count; i++)
017
{
018
Serial
.print(addr[i]>>4, HEX);
019
Serial
.print(addr[i]&0x0f, HEX);
020
Serial
.print(
" "
);
021
}
022
023
}
024
025
byte
read(
void
)
026
{
027
bool
ok =
false
;
028
uint8_t results;
029
030
oneWire.reset();
031
oneWire.select(address);
032
oneWire.write(DS2413_ACCESS_READ);
033
034
results = oneWire.read();
/* Get the register results */
035
ok = (!results & 0x0F) == (results >> 4);
/* Compare nibbles */
036
results &= 0x0F;
/* Clear inverted values */
037
038
oneWire.reset();
039
040
// return ok ? results : -1;
041
return
results;
042
}
043
044
bool
write(uint8_t state)
045
{
046
uint8_t ack = 0;
047
048
/* Top six bits must '1' */
049
state |= 0xFC;
050
051
oneWire.reset();
052
oneWire.select(address);
053
oneWire.write(DS2413_ACCESS_WRITE);
054
oneWire.write(state);
055
oneWire.write(~state);
/* Invert data and resend */
056
ack = oneWire.read();
/* 0xAA=success, 0xFF=failure */
057
if
(ack == DS2413_ACK_SUCCESS)
058
{
059
oneWire.read();
/* Read the status byte */
060
}
061
oneWire.reset();
062
063
return
(ack == DS2413_ACK_SUCCESS ?
true
:
false
);
064
}
065
066
void
setup
(
void
)
067
{
068
Serial
.begin(9600);
069
070
Serial
.println(F(
"Looking for a DS2413 on the bus"
));
071
072
/* Try to find a device on the bus */
073
oneWire.reset_search();
074
delay(250);
075
if
(!oneWire.search(address))
076
{
077
printBytes(address, 8);
078
Serial
.println(F(
"No device found on the bus!"
));
079
oneWire.reset_search();
080
while
(1);
081
}
082
083
/* Check the CRC in the device address */
084
if
(OneWire::crc8(address, 7) != address[7])
085
{
086
Serial
.println(F(
"Invalid CRC!"
));
087
while
(1);
088
}
089
090
/* Make sure we have a DS2413 */
091
if
(address[0] != DS2413_FAMILY_ID)
092
{
093
printBytes(address, 8);
094
Serial
.println(F(
" is not a DS2413!"
));
095
while
(1);
096
}
097
098
Serial
.print(F(
"Found a DS2413: "
));
099
printBytes(address, 8);
100
Serial
.println(F(
""
));
101
}
102
103
void
loop
(
void
)
104
{
105
uint8_t state = read();
106
107
108
109
const
int
IOA = 0x1;
110
const
int
IOB = 0x5;
111
// проблема с отображением информации
112
if
(state & IOA)
113
{
114
Serial
.println(
"A OFF"
);
115
116
}
117
else
118
{
119
Serial
.println(
"A ON"
);
120
121
}
122
123
124
125
if
(state & IOB)
126
{
127
Serial
.println(
"B OFF"
);
128
129
}
130
else
131
{
132
Serial
.println(
"B ON"
);
133
134
}
135
Serial
.println(state, BIN);
136
Serial
.println();
137
delay(1000);
138
139
140
/* Read */
141
/*
142
uint8_t state = read();
143
if (state == -1)
144
Serial.println(F("Failed reading the DS2413"));
145
else
146
Serial.println(state, BIN);
147
*/
148
149
150
}