DS2408. Читать научились, а писать еще нет.

GreenDer
Offline
Зарегистрирован: 06.09.2013

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

Судя по даташиту нужно записать в определённый регистр один байт. Но как это сделать ума не приложу.

Заранее благодарен.

NeiroN
NeiroN аватар
Offline
Зарегистрирован: 15.06.2013

https://github.com/search?q=DS2408

Если в даташите не понятно то глянь библиотеку которую писали еще под старую версию IDE Arduino.

GreenDer
Offline
Зарегистрирован: 06.09.2013

Спасибо. Уже смотрю... Но что-то всё равно светодиоды не моргают, морды такие.

GreenDer
Offline
Зарегистрирован: 06.09.2013

Решено.

Судя по всему какя-то ошибка(несоответствие) в файле примера. Удалил одну строку с условием и светодиоды заморгали.

Всем спасибо за внимание.

NeiroN
NeiroN аватар
Offline
Зарегистрирован: 15.06.2013

ну а написать остальным чего и как?

GreenDer
Offline
Зарегистрирован: 06.09.2013

Прошу прощения. Как-то не подумал.

#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);
            }
     //   }
        

    }
}

 

NE_XT
NE_XT аватар
Offline
Зарегистрирован: 22.05.2012

GreenDer ,

у вас  на шине подключенны 2 штуки ds2408 судя по ID устройств, на одной "висят" светодиоды, на другой физические кнопки, я правильно понимаю?

 

GreenDer
Offline
Зарегистрирован: 06.09.2013

Нет. на шине два ds2408 со светодиодами. Скетч поочередно переключает светодиоды на них. Кнопок нет.

Vittaly
Offline
Зарегистрирован: 19.04.2013

Добрый день!

Сложно сказать - переменная devices, видимо, описана в  DS2408.h, и поэтому из скеча ен понятна её структура. Ну проверить-то просто: напишите в 30-й строке (2-й скеч), что-нибудь типа:

Serial.Println(devices[index][7]);

И посмотрите, что она вам выводит: 0xBD или нет :).

GreenDer
Offline
Зарегистрирован: 06.09.2013

Да уже разобрался, спасибо.

Это явная ошибка автора скетча. index[7] это последний байт имени конкретного устройства. Т.к у меня все подключенные устройства имеют другие имена то проверка условия естественно заканчивалась false.

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

Sirocco
Offline
Зарегистрирован: 28.09.2013

Хочу реализовать удалённое управление четырьмя релюшками. Думал купить DS2408. Скажите, какие плюсы у неё? Не легче ли использовать вместо неё atmega328? atmega328 стоит 30р. Ардуинка на atmega328 стоит 80р. А DS2408 стоит от 260р. Что ей можно сделать, чего нельзя реализовать на обычной ардуино?

Vittaly
Offline
Зарегистрирован: 19.04.2013

Да всё можно реализовать обоими способами. Основная фича DS2408 - это то, что в неё уже вшит протокол 1-wire. Т.е. вам вообще не надо париться с кодом на клиентской (исполняющей) стороне. Причём реализован он хардверно, с правильными таймингами. Т.е. танцы с бубном будут сведены к минимуму. Или даже полностью исключены, если и мастер хардверный использовать. Плюс почти никакой обвязки не надо. Но это всё актуально, если у вас большие расстояния. А если 4 релюшки в одном месте (иначе зачем DS2408?), да на рассоянии в пол-метра, то смысл, конечно не очевиден. В этом случае я б в сторону I2C какого-нибудь посмотрел...

Если же расстояния большие (несколько метров и дальше), то лучше бы именно хардверные 1-Wire устройства - больше вероятность, что заработает :).

Sirocco
Offline
Зарегистрирован: 28.09.2013

Ясно. Расстояние около 15метров.

У неё 8 каналов. Есть возможность сконфигурировать четыре как вход, и четыре как выход? Нужно подавать питание на релюхи, если релюха сработала, то при запуске устройства есть подтверждающий сигнал, когда устройство запустилость и нормально функционирует сухой контакт этого устройста размыкается. Тоесть нужно на некоторые подавать, а с некоторых считывать. Считывать нужно два состояния, либо Есть сигнал, Либо нет.

Vittaly
Offline
Зарегистрирован: 19.04.2013

У неё 8 IO каналов, каждый из которых может работать как угодно и независимо друг от друга. Т.е. 4 входа/4 выхода тоже можно. При этом она как таковая не конфигурируется специально. Режим работы зависит от схемы включения. А с точки зрения софта: там 2 регистра. В один регистр вы записываете состояния, которые хотите назначить соответствующим ногам (для Outputs), а из второго считываете реальное состояние ног в данный момент (режим Input). Там всё просто. 

Я в таком режиме работал с DS2413 - это двухканальный ключ. Но работает по-аналогии.

По поводу 15 м - I2C тогда не вариант. Тогда либо какой-нибудь RS485 использовать, либо вот как раз 1-wire. Для 1-wire 15 метров - это фигня. 

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

можете поделиться примером, когда "В один регистр вы записываете состояния, которые хотите назначить соответствующим ногам (для Outputs)"?

Надо записывать все 8 состояний, или только одно, которое надо изменить?

Ни в одном из примеров в сети не удалось найти пример использования функции set_register, везде используют только set_state.

 

И в примере из поста #5 за что отвечают MODEACTIVTYSTATE,? В самой библиотеке комментарии настолько скудные, что нифига непонятно.

Vittaly
Offline
Зарегистрирован: 19.04.2013

Я работал только с DS2413. Если поможет - вечером приведу пример. Делал всё по Datasheet.

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

думаю, поможет. Они во многом схожи.

GreenDer
Offline
Зарегистрирован: 06.09.2013

Один в один. Разница только в количестве пинов.

Vittaly
Offline
Зарегистрирован: 19.04.2013

Прошу прощения, никак не получается добраться до компьютера. Если подождёте, смогу ответить в четверг.

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

Я ещё жду :)

NE_XT
NE_XT аватар
Offline
Зарегистрирован: 22.05.2012

Tomasina пишет:

Я ещё жду :)

Фигасе терпеливый какой!

где был?

 

see_watson
Offline
Зарегистрирован: 03.11.2016

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);
  */
    

}