Помогите перевести MLX90614 из PWM mode в I2C

pavel_bbb
Offline
Зарегистрирован: 27.01.2014

Помогите, как перевести пиродатчик MLX90614 из ШИМ режима в режим цифровой передачи по I2C.

Китаец прислал 5 датчиков, все в ШИМ -режиме. Голову сломал как это сделать. С программированием дружу только на уровне Ардуино. Если у кого есть решение, буду очень благодарен - в долгу не останусь, отблагодарю (финансово). Выкидывать жалко датчики.

В цифровой режим переводятся коротким подтягиванием SCL к +5 во время включения датчика, и показывают все верно.

Есть информация https://geektimes.ru/post/285226/ о том как перевести из режима ШИМ. Но мне нужно это реализовать это на уровне ардуино или каким нибудь более простым методом.

Тут есть информация http://forum.arduino.cc/index.php?topic=314581.0 как прочитать eeprom , вот бы на этом примере реализовать скетч по внесению изменений в него.

 

sadman41
Offline
Зарегистрирован: 19.10.2016
На уровне ардуино:
 
1) В setup() давать на SCL VCC (pinMode(A5, OUTPUT); digitalWrite(A5, HIGH)). Потом через пару секунд сделать digitalWrite(A5, LOW) на T > 1.44ms и вернуть в HIGH. После этого, согласно Datasheet, датчик переключится в I2C.
 
2) Если для работы не хватит п.1, то поставить https://github.com/jfitter/MLX90614, открыть пример, зачистить loop(), в сетапе сделать сначала п.1., потом mlx.writeEEProm(MLX90614_PWMCTRL, 0x0201);
 
По-моему как-то так.
pavel_bbb
Offline
Зарегистрирован: 27.01.2014

Работают оба способа!!!

Особенно спасибо за библиотеку которая может переписывать еепром датчика. Все работает. Хотя сама библиотека не совсем функционирует, но главной в ней для меня функция работает. ))

Напишите мне в личку или на почту pavts80@mail.ru свой телефон, яндекс, киви или карту сбера. Как обещал отблагодарю ))) еще раз огромнейшее спасибо.

sava
Offline
Зарегистрирован: 07.07.2016

Помогите пожалуйста у меня проблемма купил два датчика GY-906 MLX90614ESF залил скейтч, подключил и не чего не рабоает, потом залил сканнер I2C  и он не неодит не одно устройство, я так понял эти датчики прили в PWM режиме, сделал выше описанное не помогает, подскажите как быть и как вообще можно проверить их?

 

 

pavel_bbb
Offline
Зарегистрирован: 27.01.2014

Выполните только пункт 1) сначала. Если поможет и температура станет правильно отображаться, то датчики в ШИМ режиме. Если все равно не будет ничего, то деле не в ШИМ режиме. 

sava
Offline
Зарегистрирован: 07.07.2016

скажите первый пункт правельно выполнил?

pinMode(A5, OUTPUT);
 digitalWrite(A5, HIGH);
 delay(2000);
 digitalWrite(A5, LOW);
  
delayMicroseconds(1500);
  digitalWrite(A5,  HIGH);
 
   pinMode(A5, INPUT);

 

sadman41
Offline
Зарегистрирован: 19.10.2016

sava пишет:
скажите первый пункт правельно выполнил?

Похоже на правду. Только pinMode(A5, INPUT) напрасно делаете, по-моему. Сразу Wire.begin() после переключения и пошли читать/сканировать адреса...

sava
Offline
Зарегистрирован: 07.07.2016

sadman41 пишет:

sava пишет:
скажите первый пункт правельно выполнил?

Похоже на правду. Только pinMode(A5, INPUT) напрасно делаете, по-моему. Сразу Wire.begin() после переключения и пошли читать/сканировать адреса...

кстати думал нужо ли pinMode(A5, INPUT) делать или нет, но попробовал и так и так и результата нет ни какого , обидно заказал два датчика и оба не работают(((

sadman41
Offline
Зарегистрирован: 19.10.2016

Зайдите с другой стороны и проверьте их в PWM-mode. Покажут правду - значит в PWM, нет - видимо проблема с датчиком/соединением.

sava
Offline
Зарегистрирован: 07.07.2016

еще ба знать как проверить их в PWM режиме, есть скейтчи у кого примерочные?

 

DarkDaemon
Offline
Зарегистрирован: 31.10.2015

Спасибо, помогло. Тоже столкнулся с датчиком, у которого SDA пин работал в режиме PWM и шина i2c зависала. Видимо, китайцы ставят Б/У датчики, в которых не стоят настройки по-умолчанию. Вместо одной строчки я использовал функцию setEEPromDefaults, чтобы сбросить все настройки датчика по умолчанию, а то неизвестно, что там накрутили китайцы. У моего датчика много настроек было исковеркано. Так же нашел неплохую библиотеку sparkfun mlx90614, у неё ещё больше плюшек, есть режим сна и пробуждения датчика. А вот запись в EEPROM в ней не в публичных функциях, поэтому без изменения библиотеки EEPROM не записать. Но один момент я у них взял - это режим отключения PWM по пункту 1, он короче, чем в вашем примере. Выкладываю итоговый код. Сперва надо раскомментировать два участка кода в setup, выполнить его с датчиком, настройки датчика будут сброшены в режим "по умолчанию" и включится режим i2с, а потом надо обесточить всю систему, снова закомментировать эти два участка кода и наслаждаться стабильным режимом i2c.

#include <Wire.h>
#include <MLX90614.h>
MLX90614 mlx = MLX90614(MLX90614_BROADCASTADDR); //must be only one device on bus

void setup(void) {
  delay(5000);
  //pinMode(A5, OUTPUT);
  //digitalWrite(A5, LOW);
  //delay(10); // Delay at least 1.44ms
  //pinMode(A5, INPUT);
  Wire.begin(); // library does not do this by default
  Serial.begin(9600);
  mlx.begin();
  Serial.print(F("Melexis MLX90614 SMBus address = 0x"));
  Serial.print((uint8_t)mlx.readEEProm(MLX90614_ADDR), HEX);
  Serial.print(F("  Chip ID = "));
  uint64_t id = mlx.readID();
  Serial.print((uint16_t)(id >> 48));
  Serial.print("-");
  Serial.print((uint16_t)(id >> 32));
  Serial.print("-");
  Serial.print((uint16_t)(id >> 16));
  Serial.print("-");
  Serial.println((uint16_t)id);
  //dumpEEProm();
  //setEEPromDefaults();
  dumpEEProm();
  Serial.println("");
}

void loop(void) {
    static uint16_t smpcount = 0, errcount = 0;
    printlnTemp(mlx.readTemp(MLX90614::MLX90614_SRCA, MLX90614::MLX90614_TC), 'A');
    if(mlx.rwError) ++errcount;
    printlnTemp(mlx.readTemp(MLX90614::MLX90614_SRC01, MLX90614::MLX90614_TC), 'O');
    if(mlx.rwError) ++errcount;
    Serial.print(F("Samples:Errors "));
    smpcount += 2;
    Serial.print(smpcount);
    Serial.print(":");
    Serial.println(errcount);
    Serial.println("");
    delay(1000);
}

void printlnTemp(double temp, char src) {
    char str[20];
    if(mlx.rwError) Serial.print(F("No valid temperatures"));
    else {
        if(src == 'A') Serial.print(F("Ambient temperature = "));
        else Serial.print(F("Object  temperature = "));
        Serial.println(temp);
    }
    printCRC(mlx.crc8, mlx.pec);
    printErrStr(mlx.rwError);
    Serial.println("");
}

void dumpEEProm() {
    Serial.println(F("EEProm Dump"));
    for(uint8_t j=0; j<8; j++) {
        for(uint8_t i=0; i<4; i++) {
          Serial.print("0x");
          Serial.print(j*4+i, HEX);
          Serial.print("=0x");
          Serial.println(mlx.readEEProm(j*4+i), HEX);
        }
        printCRC(mlx.crc8, mlx.pec);
        printErrStr(mlx.rwError);
        Serial.println("");
    }
}

void printCRC(uint8_t crc, uint8_t pec) {
  Serial.print("crc=0x");
  Serial.print(crc, HEX);
  Serial.print(", pec=");
  Serial.print(pec, HEX);
}

void printErrStr(uint8_t err) {
    Serial.print(F("  *** "));
    if(err == MLX90614_NORWERROR) Serial.print(F("RW Success"));
    else {
        Serial.print(F("Errors: "));
        if(err &  MLX90614_DATATOOLONG) Serial.print(F("Data too long / "));
        if(err &  MLX90614_TXADDRNACK)  Serial.print(F("TX addr NACK / "));
        if(err &  MLX90614_TXDATANACK)  Serial.print(F("TX data NACK / "));
        if(err &  MLX90614_TXOTHER)     Serial.print(F("Unknown / "));
        if(err &  MLX90614_RXCRC)       Serial.print(F("RX CRC / "));
        if(err &  MLX90614_INVALIDATA)  Serial.print(F("Invalid data / "));
        if(err &  MLX90614_EECORRUPT)   Serial.print(F("EEPROM / "));
        if(err &  MLX90614_RFLGERR)     Serial.print(F("RFlags / "));
    }
}

void setEEPromDefaults(void) {
  const struct defaultEEPromData {uint8_t  address; uint16_t data;}
  eDat[] =  {{0x20, 0x9993}, {0x21, 0x62E3}, {0x22, 0x0201}, {0x23, 0xF71C}, {0x24, 0xFFFF}, {0x25, 0x9FB4}, {0x2E, 0xBE5A}, {0x2F, 0x0000}, {0x39, 0x0000}};
  for(uint8_t i = 0; i < sizeof(eDat)/sizeof(defaultEEPromData),
    !mlx.rwError; i++) { 
    mlx.writeEEProm(eDat[i].address, eDat[i].data);
  }
}

Код можно и сократить, но я решил не вырезать функции коррекции ошибок и пр. навороты.

grib
Offline
Зарегистрирован: 22.08.2021

sava пишет:

Помогите пожалуйста у меня проблемма купил два датчика GY-906 MLX90614ESF залил скейтч, подключил и не чего не рабоает, потом залил сканнер I2C  и он не неодит не одно устройство, я так понял эти датчики прили в PWM режиме, сделал выше описанное не помогает, подскажите как быть и как вообще можно проверить их?

У меня работал датчик MLX90614 на плате GY-906 и в какой-то момент перестал работать. Использовал ардуино-нано.

I2C сканер ничего не находил.

Чудесным образом заработал после того как я подключил к ногам самого датчика провода и подключил их к ардуино SCL, SDA, 5V, GND. После подключения к ардуино ничего не работало, даже ардуино выключался (переставал показывать монитор порта), потом я подключил датчик через ноги платы и все заработало, но датчик теперь работает только от 3V (от 5V как раньше не работает).

Я не понял почему так получилось, если интересно попробовать могу подробнее описать.

grib
Offline
Зарегистрирован: 22.08.2021

У меня работал датчик MLX90614 на плате GY-906 и в какой-то момент перестал работать. Использовал ардуино-нано.

I2C сканер ничего не находил.

Чудесным образом заработал после того как я подключил к ногам самого датчика провода и подключил их к ардуино SCL, SDA, 5V, GND. После подключения к ардуино ничего не работало, даже ардуино выключался (переставал показывать монитор порта), потом я подключил датчик через ноги платы и все заработало, но датчик теперь работает только от 3V (от 5V как раньше не работает).

Я не понял почему так получилось, если интересно попробовать могу подробнее описать.