Jump to content
ximik_se

Датчик температуры и влажности CJMCU-1080 HDC1080 на ATtiny85

Recommended Posts

Всем привет.

Решил сделать небольшую домашнюю метеостанцию.

Есть приемник с экраном, куда выводится инфа (построено на ATMEGA 328P) и есть передатчик, который посылает инфу по возудху (построено на ATtiny85).

В передатчике использую обычные DHT22. В принципе качество чуть ниже среднего. Но главный недостаток - порой сбоит, присылая данные в 2 раза больше предидущих, потом опять приходит в себя. и так повторяется постоянно.

При этом время между измерениями не меньше 20 сек.

В общем заказал я себе с Китаюшки более точные датчики - 

CJMCU-1080 HDC1080
Вещица прекрасная, но общается по I2C.

А библиотеку рабочую под нее я смог найти только одну "ClosedCube_HDC1080.h" и никаких модификаций под ATtiny я найти не смог.

Для ее работы соответственно нужен Wire.h

В общем решил я его поковырять самостоятельно, хоть и не прогер. Забрался во внутренности ClosedCube_HDC1080.cpp и везде заменил Wire на TinyWireM (некий аналог Wire для ATtiny).

И у меня даже получилось считывать валжность, но вот вместо температуры приходит гадость. Ибо при компиляции Arduino IDE ругалась на строку (я ее ниже в коде закомментировал)

    uint8_t buf[4];
    for (int i = 1; i < (seconds*66); i++) {
        TinyWireM.beginTransmission(_address);
        TinyWireM.write(0x00);
        TinyWireM.endTransmission();
        delay(20);
        TinyWireM.requestFrom(_address, (uint8_t)4);
//        TinyWireM.readBytes(buf, (size_t)4);
    }

Ошибку пишет следующую:

\ClosedCube_HDC1080.cpp: In member function 'void ClosedCube_HDC1080::heatUp(uint8_t)':

\ClosedCube_HDC1080.cpp:81:13: error: 'class USI_TWI' has no member named 'readBytes'

TinyWireM.readBytes(buf, (size_t)4);
Может есть ребята более понимающие в коде и сумеющие победить эту проблему, чтобы и температуру этот датчик смог передавать через ATtiny85.

Вот полный текст файла ClosedCube_HDC1080.cpp (уже замененный ну и строчка закоментирована):

#include <TinyWireM.h>

#include "ClosedCube_HDC1080.h"


ClosedCube_HDC1080::ClosedCube_HDC1080()
{
}

void ClosedCube_HDC1080::begin(uint8_t address) {
    _address = address;
    TinyWireM.begin();

        // Heater off, 14 bit Temperature and Humidity Measurement Resolution
    TinyWireM.beginTransmission(_address);
    TinyWireM.write(CONFIGURATION);
    TinyWireM.write(0x0);
    TinyWireM.write(0x0);
    TinyWireM.endTransmission();

}

HDC1080_Registers ClosedCube_HDC1080::readRegister() {
    HDC1080_Registers reg;
    reg.rawData = (readData(CONFIGURATION) >> 8);
    return reg;
}

void ClosedCube_HDC1080::writeRegister(HDC1080_Registers reg) {
    TinyWireM.beginTransmission(_address);
    TinyWireM.write(CONFIGURATION);
    TinyWireM.write(reg.rawData);
    TinyWireM.write(0x00);
    TinyWireM.endTransmission();
    delay(10);
}

void ClosedCube_HDC1080::heatUp(uint8_t seconds) {
    HDC1080_Registers reg = readRegister();
    reg.Heater = 1;
    reg.ModeOfAcquisition = 1;
    writeRegister(reg);

    uint8_t buf[4];
    for (int i = 1; i < (seconds*66); i++) {
        TinyWireM.beginTransmission(_address);
        TinyWireM.write(0x00);
        TinyWireM.endTransmission();
        delay(20);
        TinyWireM.requestFrom(_address, (uint8_t)4);
//        TinyWireM.readBytes(buf, (size_t)4);
    }
    reg.Heater = 0;
    reg.ModeOfAcquisition = 0;
    writeRegister(reg);
}

float ClosedCube_HDC1080::readT() {
    return readTemperature();
}

float ClosedCube_HDC1080::readTemperature() {
    uint16_t rawT = readData(TEMPERATURE);
    return (rawT / pow(2, 16)) * 165 - 40;
}

float ClosedCube_HDC1080::readH() {
    return readHumidity();
}

float ClosedCube_HDC1080::readHumidity() {
    uint16_t rawH = readData(HUMIDITY);
    return (rawH / pow(2, 16)) * 100;
}

uint16_t ClosedCube_HDC1080::readManufacturerId() {
    return readData(MANUFACTURER_ID);
}

uint16_t ClosedCube_HDC1080::readDeviceId() {
    return readData(DEVICE_ID);
}

uint16_t ClosedCube_HDC1080::readData(uint8_t pointer) {
    TinyWireM.beginTransmission(_address);
    TinyWireM.write(pointer);
    TinyWireM.endTransmission();
    delay(9);
    TinyWireM.requestFrom(_address, (uint8_t)2);
    byte msb = TinyWireM.read();
    byte lsb = TinyWireM.read();
    return msb << 8 | lsb;
}

 

Share this post


Link to post
Share on other sites

По ходу нужно заменить TinyWireM.readBytes(buf, (size_t)4); на TinyWireM.readBytes(buf, (uint8_t)4); это к этому \ClosedCube_HDC1080.cpp: In member function 'void ClosedCube_HDC1080::heatUp(uint8_t)':

К тому же в библиотеке ClosedCube_HDC1080  'class USI_TWI' нет такого оператора 'readBytes' ,

Попробуй так:  TinyWireM.read(buf, (uint8_t)4);

Edited by Электронщик

Share this post


Link to post
Share on other sites
10 часов назад, ximik_se сказал:

void ClosedCube_HDC1080::heatUp(uint8_t seconds)

Эта функция служит для просушки датчика влажности. Её можно не использовать или вместо закомментированной строки вставить

buf[0] = TinyWireM.read();

buf[1] = TinyWireM.read();

buf[2] = TinyWireM.read();

buf[3] = TinyWireM.read();

 

Share this post


Link to post
Share on other sites

Металл-композит как альтернатива ферриту: дроссели Panasonic семейства ETQP

Современные электронные устройства требуют все более компактных и эффективных компонентов. Новые металл-композитные дроссели обладают рядом преимуществ перед дросселями с ферритовым сердечником. Они не имеют ярко выраженного насыщения, обладают отличными частотными свойствами и способны работать при температурах до 150°C и выше. Все это делает их альтернативой стандартным дросселям с ферритовым сердечником в широком спектре автомобильных и промышленных приложений.

Подробнее

В 26.05.2017 в 00:15, Электронщик сказал:

По ходу нужно заменить TinyWireM.readBytes(buf, (size_t)4); на TinyWireM.readBytes(buf, (uint8_t)4); это к этому \ClosedCube_HDC1080.cpp: In member function 'void ClosedCube_HDC1080::heatUp(uint8_t)':

К тому же в библиотеке ClosedCube_HDC1080  'class USI_TWI' нет такого оператора 'readBytes' ,

Попробуй так:  TinyWireM.read(buf, (uint8_t)4);

К сожалению, он продолжает ругаться.

Но это не важно. Я решил проблему, точнее нашел корень зла в этом вопросе ))

Когда я закомментил строчку и залил код. то влажность у меня показывалась верно. а вот температуру показывал "-39" - чушь.

Так вот это хрень вылазиет, если после подачи питания коснуться датчика - видеть легкое дребезжание контактов приводит к каким-то сбоям.

Это же происходило, когда я его подключал к УНЕ на прямую. решалось просо перезапуском уны.

А тут я этого не учел, ведь питание на считывающий микроконтроллер было постоянным и я его не перезапускал.

Спасибо ВАМ большое, что отозвались на тему!

В 26.05.2017 в 03:02, snn_krs сказал:

Эта функция служит для просушки датчика влажности. Её можно не использовать или вместо закомментированной строки вставить

buf[0] = TinyWireM.read();

buf[1] = TinyWireM.read();

buf[2] = TinyWireM.read();

buf[3] = TinyWireM.read();

 

Я поставил ваш код. Не ругается. Но оказалось, что проблема в другом была! И я ее решил, точнее понял и убрал ))

Выше я ответил и вам продублирую свой ответ, т.к. вы так же, как предидущий пользовались ответили на мой крик о помощи!

Когда я закомментил строчку и залил код. то влажность у меня показывалась верно. а вот температуру показывал "-39" - чушь.

Так вот это хрень вылазиет, если после подачи питания коснуться датчика - видеть легкое дребезжание контактов приводит к каким-то сбоям.

Это же происходило, когда я его подключал к УНЕ на прямую. решалось просо перезапуском уны.

А тут я этого не учел, ведь питание на считывающий микроконтроллер было постоянным и я его не перезапускал.

Спасибо ВАМ большое, что отозвались на тему!

Share this post


Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Similar Content

    • By Kovalinski
      Добрый день! Прошу помощи в реализации интерфейса TWI на XMEGA. Набросал код для двух микроконтроллеров.  Но на выходе SDA и SCL вообще ничего не происходит. Привожу пример для мастера. 
      #define F_CPU 2000000UL #define CPU_SPEED 2000000 #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> uint8_t slave_address=6, write=0; uint8_t data=0x01; void TWI_init(void) {     TWIC.CTRL=0;     TWIC.MASTER.BAUD=0x05;     TWIC.MASTER.CTRLA=TWI_MASTER_INTLVL_HI_gc|TWI_MASTER_ENABLE_bm|TWI_MASTER_WIEN_bm;     TWIC.MASTER.CTRLB=0;     TWIC.MASTER.CTRLC=0;     TWIC.MASTER.STATUS=TWI_MASTER_BUSSTATE_IDLE_gc; } void TWI_write_date(uint8_t data) {     //TWIC.MASTER.CTRLC=TWI_MASTER_CMD_REPSTART_gc;     TWIC.MASTER.ADDR=slave_address|write;     while(!(TWIC.MASTER.STATUS&TWI_MASTER_WIF_bm));     TWIC.MASTER.DATA=data;     while(!(TWIC.MASTER.STATUS & TWI_MASTER_WIF_bm));     TWIC.MASTER.DATA=data;     while(!(TWIC.MASTER.STATUS & TWI_MASTER_WIF_bm));     TWIC.MASTER.CTRLC=TWI_MASTER_ACKACT_bm|TWI_MASTER_CMD_STOP_gc;     TWIC.MASTER.CTRLC=0; } int main(void) {     CPU_SREG|=(1<<CPU_I_bp);     TWI_init();     while(1)     {         TWI_write_date(data);     } }  
    • By jams
      Приветствую всех! Предистория:
      Пришла мне на ремонт швейная машинка с сервоприводом и неисправной педалью. 3 провода, питание +/- и управление. Ткунул тесером ничего не происходит. Разобрал, внутри датчик Холла. Ясно что он не исправен. 
      Теперь по делу:
      Датчик фото:

       Даташит:  MT4501 линейный датчик Холла.
      А теперь вопрос к знатокам. Есть ли распространенный аналог?
    • By Emelyannof
      OMRON E32-DC200E 2M - Головка оптоволоконного датчика диффузного типа, кабель 2м.
      1000р
      +79997687609Дмитрий

    • By Денис216
      Не могу опросить магнитометр по I2C. На линиях какие-то сигналы проскакивают, но никакого результата не могу достичь. Кто-то что-то знает по этому поводу? Как заставить работать его.


       
      #include "stm32f30x.h"              int a1=0, j=0; int main(void) { RCC->AHBENR|=RCC_AHBENR_GPIOBEN;// тактирование портa B включено RCC->AHBENR|=RCC_AHBENR_GPIOEEN;//21 тактирование портa Е включено RCC->APB1ENR|=RCC_APB1ENR_I2C1EN;// тактирование I2C1 включено GPIOB->MODER|=0x0000A000; // альтернативная функция линий PB7,PB6 GPIOB->OTYPER|=(1<<6);  //настройка линии PB7 на выход открытый сток GPIOB->OTYPER|=(1<<7);  //настройка линии PB6 на выход открытый сток GPIOB->OSPEEDR=0xFFFFFFFF; GPIOB->AFR[0] |= 0x44000000;  //настройка линий PB7,PB6 на функцию AF4 GPIOE->MODER=0x55555555; //настройка порта Е на выход EXTI->EMR=1<<23; EXTI->IMR=1<<23; NVIC_EnableIRQ(I2C1_EV_IRQn); //инициализация I2C мастер I2C1->CR1=(0<<0); //PE=0 I2C1->TIMINGR=(0x4<<28);//PRESC[3:0]: Timing prescaler I2C1->TIMINGR=(0x8<<20);//SCLDEL[3:0]: Data setup time I2C1->TIMINGR=(0x8<<16);//SDADEL[3:0]: Data hold time I2C1->TIMINGR=(0xC3<<8);//SCLH[7:0]: SCL high period (master mode) I2C1->TIMINGR=(0xC7<<0);//SCLL[7:0]: SCL low period (master mode) I2C1->CR1=(0<<17);//для мастера = 0 NOSTRETCH: Clock stretching disable I2C1->CR1=(1<<6);//TCIE: Transfer Complete interrupt enable I2C1->CR1=(1<<2);//RXIE: RX Interrupt enable(RXNE) I2C1->CR1=(1<<1);//TXIE: TX Interrupt enable(TXIS) I2C1->CR2=(0<<11);//ADD10=0 -7 bits I2C1->CR2=(0<<10);//RD_WRN=0 передача I2C1->CR2=(1<<25);//AUTOEND I2C1->CR1|=(1<<0); //PE=1 I2C1->CR2 = 0x03<<1;//adress  I2C1->CR2|=1<<13;//start ?????? a1=I2C1->RXDR;     while (1){     //    I2C1->CR2|=1<<13;//start         if((a1&0x1)>0)    GPIOE->ODR =1<<9;         else            GPIOE->ODR =(0<<9);         if((a1 & 0x2)>0)    GPIOE->ODR |=1<<10;         else            GPIOE->ODR &= ~(1<<10);         if((a1 & 0x4)>0)    GPIOE->ODR |=1<<11;         else            GPIOE->ODR &= ~(1<<11);         if((a1 & 0x8)>0)    GPIOE->ODR |=1<<12;         else            GPIOE->ODR &= ~(1<<12);         if((a1 & 0x10)>0)    GPIOE->ODR |=1<<13;         else            GPIOE->ODR &= ~(1<<13);         if((a1 & 0x20)>0)    GPIOE->ODR |=1<<14;         else            GPIOE->ODR &= ~(1<<14);         if((a1 & 0x40)>0)    GPIOE->ODR |=1<<15;         else            GPIOE->ODR &= ~(1<<15);         if((a1 & 0x80)>0)    GPIOE->ODR |=1<<8;         else            GPIOE->ODR &= ~(1<<8); }} void I2C1_EV_EXTI23_IRQHandler () {a1=2;}  
    • By Anton Bondarenko
      Всем привет
      Прошу не ругать, впервые подобный вопрос задаю.
      Хочу сделать прибор, который будет посылать сигнал, когда возле прибора будет проходить металлический предмет. 
      — угол отслеживания до 30° а лучше прямая линия, траектория
      — время реакции очень высокое до 100 мс
      — ширина проема в котором нужно сканировать от 10 до 20метров,
      — передача сигнала через вифи
      Может есть готовые решения, или отдельные компоненты.
      Подскажите пжл в каком направлении искать.
      Смотрел датчики движения, но главная проблема — время реакции.
      Спасибо
       
×
×
  • Create New...