Считать данные с DS2406

Romosyto
Offline
Зарегистрирован: 15.01.2014

Здравствуйте. Помогите пожалуйста разобраться с двухканальным 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). Чего по идее (согласно даташиту) не должно быть.

Помогите разобраться пожалуйста. Спасибо.

 

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

В свое время руки не дошли научиться читать, вот списочек  может вам поможет.

ds.write(0x33); // Read ROM 
ds.write(0x55); // Match ROM 
ds.write(0xCC); // Skip ROM 
ds.write(0x0F); // Search ROM 
ds.write(0x4E); // Write Scratchpad 
ds.write(0xBE); // Read Scratchpad 
ds.write(0x48); // Copy Scratchpad
ds.write(0xB8); // Recall EEprom 
ds.write(0x44); // Convert Sensor 
ds.write(0x45); // Read Sensor 
ds.write(0x01); // Reset Counter 
ds.write(0x02); // Read Counter 
ds.write(0x03); // Read IO-identification
ds.write(0xF3); // Setup PortA 
ds.write(0xF4); // Setup PortB 
ds.write(0xF5); // Read PortA 
ds.write(0xF6); // Read PortB 
ds.write(0xF7); // Write PortA 
ds.write(0xF8); // Write PortB 

 

Romosyto
Offline
Зарегистрирован: 15.01.2014

Спасибо за наводку))) А Вы это все из даташита вычитали? Я просто видимо не нашел или не понял как именно эти коды выделить из тех таблиц. Буду пробовать

n1ki7a
Offline
Зарегистрирован: 17.02.2014

Romosyto, у вас получилось разобраться как работать с ds2406?

Romosyto
Offline
Зарегистрирован: 15.01.2014

Да, получилось) Код дома на компе. Вечером отпишусь...

n1ki7a
Offline
Зарегистрирован: 17.02.2014

Ок. Жду. Спасибо.

Romosyto
Offline
Зарегистрирован: 15.01.2014

После безуспешных поисков на форумах и в инете, вот что удалось набыдлокодить)) :

#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 и памятью - поделитесь опытом)

n1ki7a
Offline
Зарегистрирован: 17.02.2014

Большое спасибо. Попробую. Если что-то додумаю обязательно поделюсь.

n1ki7a
Offline
Зарегистрирован: 17.02.2014
#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);
}

вот что у меня получилось.

Romosyto
Offline
Зарегистрирован: 15.01.2014

И как? работает?

Можно по подробнее про CRC?

Про вот эту строчку "// 3 cmd bytes, 1 data byte, 1 0x00, 2 CRC16" ?