Как считать адреса на нескольких платах DS2413 1-Wire GPIO, используя скетч Adafruit?
Я использую три DS2413 1-Wire GPIO Breakouts от Adafruit, подключенные к ESP8266. Я протестировал DS2413 breakouts, используя их пример эскиза, и он отлично работает только для одного DS2413. Но я не могу заставить его работать, когда подключены 2 или более DS2413.
Пример эскиза Adafruit DS2413 https://github.com/adafruit/Adafruit_DS2413/blob/master/DS2413.pde
Обзор Adafruit DS2413
https://learn.adafruit.com/adafruit-1-wire-gpio-breakout-ds2413?view=all
Когда я подключаю 2 или более DS2413, мигают только светодиоды, подключенные к 1-му разъему, и не считываются другие адреса.
Я внес некоторые изменения в раздел void setup, и теперь я получаю следующее в последовательном мониторе. Он видит все адреса, но дублирует их, и в первом наборе в конце есть "No device found on the bus!". Как мне заставить скетч считывать все адреса без этих ошибок?
Последовательный монитор
Looking for a DS2413 on the bus
3A B2 C2 39 00 00 00 8C No device found on the bus!
3A 8E AE 39 00 00 00 2C No device found on the bus!
3A E5 B6 39 00 00 00 55 No device found on the bus!
Found a DS2413: 3A B2 C2 39 00 00 00 8C
Found a DS2413: 3A 8E AE 39 00 00 00 2C
Found a DS2413: 3A E5 B6 39 00 00 00 55
Вот код с моими изменениями.
#include <OneWire.h>
#define DS2413_ONEWIRE_PIN (4)
#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);
while (oneWire.search(address)) {
printBytes(address, 8);
Serial.println(F("No device found on the bus!"));
}
/* Check the CRC in the device address */
if (OneWire::crc8(address, 7) != address[7])
{
Serial.println(F("Invalid CRC!"));
return;
}
/* Make sure we have a DS2413 */
if (address[0] != DS2413_FAMILY_ID)
{
printBytes(address, 8);
Serial.println(F(" is not a DS2413!"));
return;
}
while (oneWire.search(address)) {
Serial.print(F("Found a DS2413: "));
printBytes(address, 8);
Serial.println(F(""));
}
}
void loop(void)
{
/* Read */
/*
uint8_t state = read();
if (state == -1)
Serial.println(F("Failed reading the DS2413"));
else
Serial.println(state, BIN);
*/
/* Write */
bool ok = false;
ok = write(0x3);
if (!ok) Serial.println(F("Wire failed"));
delay(1000);
ok = write(0x0);
if (!ok) Serial.println(F("Wire failed"));
delay(1000);
}
@EpixRu, 👍0
2 ответа
Лучший ответ:
Мне удалось заставить ESP8266 считывать все устройства DS2413 без ошибок, а также мигать каждым светодиодом, подключенным к DS2413, по отдельности, по всей цепочке.
Вот анимация того, как это работает.
Я полностью благодарен mortonkopf на Github. Его эскиз DS2413_button_array_test был именно тем, что мне было нужно, чтобы иметь возможность считывать адреса на всех подключенных устройствах DS2413 и мигать каждым светодиодом. Вот ссылка на его репозиторий OneWire_DS2413_array.
https://github.com/mortonkopf/OneWire_DS2413_array
Вот код, который я использую, чтобы это работало.
// Этот эскиз основан на эскизе DS2413_button_array_test от mortonkopf и позволяет
// вы можете считать данные с нескольких устройств DS2413 и мигать светодиодом, подключенным к каждому DS2413,
// индивидуально, по цепочке.
// https://github.com/mortonkopf/OneWire_DS2413_array
//
// Этот эскиз представляет собой усовершенствованную функцию записи Adafruit DS2413
// скетч, который считывает только 1 устройство DS2413.
// https://github.com/adafruit/Adafruit_DS2413
// https://learn.adafruit.com/adafruit-1-wire-gpio-breakout-ds2413/reading-writing-and-arithmatic
#include <OneWire.h>
/* reading pins
0x0 (B00000000) - Both pins LOW
0x1 (B00000001) - IOA = HIGH, IOB = LOW
0x2 (B00000010) - IOA = LOW, IOB = HIGH
0x3 (B00000011) - Both pins HIGH
0xFF (B11111111) - Read Failed!
*/
#define DS2413_ONEWIRE_PIN (4) // GPIO 4 на Adafruit Feather HUZZAH ESP8266
#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
#define BUTTON_NO 3 //используйте это для размера массива для хранения значений состояния//
OneWire oneWire(DS2413_ONEWIRE_PIN);
uint8_t address[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
byte Button_states[BUTTON_NO];//это массив состояний кнопок//
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();
// вернуть ok ? результаты : -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"));
}
void loop(void) {
byte i;
byte present = 0;
byte data[12];
byte addr[8];
if ( !oneWire.search(address)) {
Serial.println("");
Serial.print("No more addresses.\n");
oneWire.reset_search();
delay(50); //было 250
return;
}
Serial.println("");
Serial.print("R=");
for( i = 0; i < 8; i++) {
Serial.print(address[i], HEX);
Serial.print(" ");
}
if ( OneWire::crc8( address, 7) != address[7]) {
Serial.print("CRC is not valid!\n");
return;
}
if ( address[0] != DS2413_FAMILY_ID) {
Serial.print("Device is not a DS2413 family device.\n");
return;
}
// Поочередно мигать каждым светодиодом, подключенным к DS2413
bool ok = false;
ok = write(0x1);
if (!ok) Serial.println(F("Wire failed"));
delay(200);
ok = write(0x2);
if (!ok) Serial.println(F("Wire failed"));
delay(200);
ok = write(0x0);
if (!ok) Serial.println(F("Wire failed"));
delay(200);
///////////////////
uint8_t state = read();
const int IOA = 0x1;
const int IOB = 0x2;
if (state == -1)
{
Serial.println(F("Failed reading the DS2413"));
}
else
{
if (state & IOA)
{
Serial.print(" A");
}
if (state & IOB)
{ //можно использовать этот ввод-вывод при необходимости для выполнения задач
Serial.print(" B");
}
}
}
Вот ссылка на Gist, который я создал для этого наброска. https://gist.github.com/orbitrod/51eb10c1a88f5747dc79298030e4480c
В вашей функции настройки есть два контура обнаружения. Его можно смело удалить, так как для каждого обнаруженного устройства будет выведено сообщение об ошибке.
while (oneWire.search(address)) {
printBytes(address, 8);
Serial.println(F("No device found on the bus!"));
}
- Легкий сон ESP8266 — не могу проснуться
- Adafruit Huzzah espcomm_open не удалось
- Понимание того, как запитать объекты с помощью реле (featherwing, feather huzzah)
- Обновление прошивки на Adafruit Huzzah ESP8266
- Adafruit esp32 Feather не удалось скомпилировать
- Почему я получаю ошибку "SendCommand не был объявлен"
- Проводка ESP8266 для MFRC522
- Обнаружение датчиков DS18B20 и правильное назначение их реле