2. Прошивку в формате hex, вряд ли кто то будет ковырять, а вот скетч, в формате ino, могли бы посмотреть.
3. Попробуйте подключить один датчик bme 280 без всяких прибамбасов, залить тестовый скетч и проверить показания датчика в мониторе порта, к примеру...
#include <Wire.h>
#define BME280_ADDRESS 0x76
unsigned long int hum_raw,temp_raw,pres_raw;
signed long int t_fine;
uint16_t dig_T1;
int16_t dig_T2;
int16_t dig_T3;
uint16_t dig_P1;
int16_t dig_P2;
int16_t dig_P3;
int16_t dig_P4;
int16_t dig_P5;
int16_t dig_P6;
int16_t dig_P7;
int16_t dig_P8;
int16_t dig_P9;
int8_t dig_H1;
int16_t dig_H2;
int8_t dig_H3;
int16_t dig_H4;
int16_t dig_H5;
int8_t dig_H6;
void setup()
{
uint8_t osrs_t = 1; //Temperature oversampling x 1
uint8_t osrs_p = 1; //Pressure oversampling x 1
uint8_t osrs_h = 1; //Humidity oversampling x 1
uint8_t mode = 3; //Normal mode
uint8_t t_sb = 5; //Tstandby 1000ms
uint8_t filter = 0; //Filter off
uint8_t spi3w_en = 0; //3-wire SPI Disable
uint8_t ctrl_meas_reg = (osrs_t << 5) | (osrs_p << 2) | mode;
uint8_t config_reg = (t_sb << 5) | (filter << 2) | spi3w_en;
uint8_t ctrl_hum_reg = osrs_h;
Serial.begin(9600);
Wire.begin();
writeReg(0xF2,ctrl_hum_reg);
writeReg(0xF4,ctrl_meas_reg);
writeReg(0xF5,config_reg);
readTrim(); //
}
void loop()
{
double temp_act = 0.0, press_act = 0.0,hum_act=0.0;
signed long int temp_cal;
unsigned long int press_cal,hum_cal;
readData();
temp_cal = calibration_T(temp_raw);
press_cal = calibration_P(pres_raw);
hum_cal = calibration_H(hum_raw);
temp_act = (double)temp_cal / 100.0;
press_act = (double)press_cal / 100.0;
hum_act = (double)hum_cal / 1024.0;
Serial.print("TEMP : ");
Serial.print(temp_act);
Serial.print(" DegC PRESS : ");
Serial.print(press_act);
Serial.print(" hPa HUM : ");
Serial.print(hum_act);
Serial.println(" %");
delay(1000);
}
void readTrim()
{
uint8_t data[32],i=0;
Wire.beginTransmission(BME280_ADDRESS);
Wire.write(0x88);
Wire.endTransmission();
Wire.requestFrom(BME280_ADDRESS,24);
while(Wire.available()){
data[i] = Wire.read();
i++;
}
Wire.beginTransmission(BME280_ADDRESS);
Wire.write(0xA1);
Wire.endTransmission();
Wire.requestFrom(BME280_ADDRESS,1);
data[i] = Wire.read();
i++;
Wire.beginTransmission(BME280_ADDRESS);
Wire.write(0xE1);
Wire.endTransmission();
Wire.requestFrom(BME280_ADDRESS,7);
while(Wire.available()){
data[i] = Wire.read();
i++;
}
dig_T1 = (data[1] << 8) | data[0];
dig_T2 = (data[3] << 8) | data[2];
dig_T3 = (data[5] << 8) | data[4];
dig_P1 = (data[7] << 8) | data[6];
dig_P2 = (data[9] << 8) | data[8];
dig_P3 = (data[11]<< 8) | data[10];
dig_P4 = (data[13]<< 8) | data[12];
dig_P5 = (data[15]<< 8) | data[14];
dig_P6 = (data[17]<< 8) | data[16];
dig_P7 = (data[19]<< 8) | data[18];
dig_P8 = (data[21]<< 8) | data[20];
dig_P9 = (data[23]<< 8) | data[22];
dig_H1 = data[24];
dig_H2 = (data[26]<< 8) | data[25];
dig_H3 = data[27];
dig_H4 = (data[28]<< 4) | (0x0F & data[29]);
dig_H5 = (data[30] << 4) | ((data[29] >> 4) & 0x0F);
dig_H6 = data[31];
}
void writeReg(uint8_t reg_address, uint8_t data)
{
Wire.beginTransmission(BME280_ADDRESS);
Wire.write(reg_address);
Wire.write(data);
Wire.endTransmission();
}
void readData()
{
int i = 0;
uint32_t data[8];
Wire.beginTransmission(BME280_ADDRESS);
Wire.write(0xF7);
Wire.endTransmission();
Wire.requestFrom(BME280_ADDRESS,8);
while(Wire.available()){
data[i] = Wire.read();
i++;
}
pres_raw = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4);
temp_raw = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4);
hum_raw = (data[6] << 8) | data[7];
}
signed long int calibration_T(signed long int adc_T)
{
signed long int var1, var2, T;
var1 = ((((adc_T >> 3) - ((signed long int)dig_T1<<1))) * ((signed long int)dig_T2)) >> 11;
var2 = (((((adc_T >> 4) - ((signed long int)dig_T1)) * ((adc_T>>4) - ((signed long int)dig_T1))) >> 12) * ((signed long int)dig_T3)) >> 14;
t_fine = var1 + var2;
T = (t_fine * 5 + 128) >> 8;
return T;
}
unsigned long int calibration_P(signed long int adc_P)
{
signed long int var1, var2;
unsigned long int P;
var1 = (((signed long int)t_fine)>>1) - (signed long int)64000;
var2 = (((var1>>2) * (var1>>2)) >> 11) * ((signed long int)dig_P6);
var2 = var2 + ((var1*((signed long int)dig_P5))<<1);
var2 = (var2>>2)+(((signed long int)dig_P4)<<16);
var1 = (((dig_P3 * (((var1>>2)*(var1>>2)) >> 13)) >>3) + ((((signed long int)dig_P2) * var1)>>1))>>18;
var1 = ((((32768+var1))*((signed long int)dig_P1))>>15);
if (var1 == 0)
{
return 0;
}
P = (((unsigned long int)(((signed long int)1048576)-adc_P)-(var2>>12)))*3125;
if(P<0x80000000)
{
P = (P << 1) / ((unsigned long int) var1);
}
else
{
P = (P / (unsigned long int)var1) * 2;
}
var1 = (((signed long int)dig_P9) * ((signed long int)(((P>>3) * (P>>3))>>13)))>>12;
var2 = (((signed long int)(P>>2)) * ((signed long int)dig_P8))>>13;
P = (unsigned long int)((signed long int)P + ((var1 + var2 + dig_P7) >> 4));
return P;
}
unsigned long int calibration_H(signed long int adc_H)
{
signed long int v_x1;
v_x1 = (t_fine - ((signed long int)76800));
v_x1 = (((((adc_H << 14) -(((signed long int)dig_H4) << 20) - (((signed long int)dig_H5) * v_x1)) +
((signed long int)16384)) >> 15) * (((((((v_x1 * ((signed long int)dig_H6)) >> 10) *
(((v_x1 * ((signed long int)dig_H3)) >> 11) + ((signed long int) 32768))) >> 10) + (( signed long int)2097152)) *
((signed long int) dig_H2) + 8192) >> 14));
v_x1 = (v_x1 - (((((v_x1 >> 15) * (v_x1 >> 15)) >> 7) * ((signed long int)dig_H1)) >> 4));
v_x1 = (v_x1 < 0 ? 0 : v_x1);
v_x1 = (v_x1 > 419430400 ? 419430400 : v_x1);
return (unsigned long int)(v_x1 >> 12);
}
1. Про защиту от осадков пока вопос открытый пока использую просто пластиковый контейнер с мелкими дырочками для вентиляции. Насекомых думаю не стоит особо опасаться. Особенно на 6-м этаже. У нас их тут в принципе мало.
2. Схему подключения нарисовал. Правда в библиотеке не было моего модуля. Поставил какой был. У меня такой. На нём явно есть стабилизатор. Значит питать можно от 5 вольт. Скетч прилагаю.
3. Провода обычные... Для макетки. Вот фото в сборе.
4. Вообще конечно погрешность грустная. Вряд ли такой модуль подходит для уличного термометра...
Я извиняюсь, а не подскажете скетч у Вас в чём?
Просто как то привык что скетч идёт с .ino на конце.
Просто как то привык что скетч идёт с .ino на конце.
P.S. из архива распаковал.
Этот скетч я делал для PlatformIO. Довольно удобная среда для программирования. Ardiuino IDE как IDE всё-таки совершено убог. Где-то в прошлом веке остался. Примерно в его начале
Ну и потом. Разве может помешать кондесатор на питании? Подтягивающие резисторы на шине i2c? Какое они могут оказать влияние на измерения датчика? Что даст проверка показаний в мониторе порта? Показания идут. С этим проблем нет. Вопрос в том как проверить их правильность?
Ну и потом. Разве может помешать кондесатор на питании? Подтягивающие резисторы на шине i2c? Какое они могут оказать влияние на измерения датчика? Что даст проверка показаний в мониторе порта? Показания идут. С этим проблем нет. Вопрос в том как проверить их правильность?
Вот Вы и проверьте, с показаниями обычного ртутного термометра...
Ну, Вы знаете, людям свойственно приписывать всему старому самые замечательные свойства :)
Если бы Вы часто бывали на хоккейных стадионах и были бы примерно моего возрата, то наверняка согласились бы с моим мнением: "Вот лет сорок назад ... и лёд блестел ярче, и шайбы лучше скользили, и девки на трибунах пофигуристее были" :)
С температурой все понятно, а вот как проверить правильность показания влажности... У меня три латчика, правдва все китайские, показывают три разных значения :)
С температурой все понятно, а вот как проверить правильность показания влажности... У меня три латчика, правдва все китайские, показывают три разных значения :)
У разных датчиков - разная погрешность и диапазон измерений...
Как вариант, узнайте телефон местной (городской) метеостанции, запросите у них значения относительной влажности для вашего населенного пункта и проведите замеры относительной влажности рядом с вашей метеостанцией...
Вы все равно с этими "разными типами" работаете в коде как с непрерывным байтовым массивом. Тасуете их туда-сюда, преобразуете по своей прихоти то в 32битный лонг. то в 64-битный лонг лонг. Ну и какй смысл был давать этим полям отдельные названия? - зададли бы непрерывный массив да и все
И что помешало в строчках 82-93 всю структуру прочитать по i2c одним блоком?
Вы все равно с этими "разными типами" работаете в коде как с непрерывным байтовым массивом. Тасуете их туда-сюда, преобразуете по своей прихоти то в 32битный лонг. то в 64-битный лонг лонг
Это по делу написано. Не получается у меня одним циклом в масив все прочесть. Если меняю типы данных dig_P1..dig_P9 на uint16_t..int16_t..uint32_t..int32_t, не трогая основной код, то получаю неверный результат давления
Например dig_P2 при неверном типе печатается в сериал как D668 а при верном как FFFFD668. Тут я и не соображу почему FFFF добавляется. Конечно было бы проще в один масив считать все и сразу. Знаю что это можно сделать для dig_P2..dig_P9.
С этими датчиками, на длинной линии желательны подтягивающие резисторы.
На какой стороне их правильнее ставить? На стороне датчика или на стороне ардуины?
PS
так получилось, что использован именно такой датчик и именно на длинной линии. Кабель - не помню, как называется, но просто тонкий четырех проводный (типа телефонного). Система постоянно сбоит. Однократно, при перезагрузке по питанию, считывает, а потом начинает врать. При стендировании, в лабораторных условиях, на том же кабеле, все работало без сбоев.
Коротко проект такой - датчик в презервативе - помещается на дно бочки и по давлению считается заполненность бочки. Есть кнопка обнуления (можно поднять датчик на поверхность, сбросить показания и считать их за Ноль. Верхний срез бочки примерно на уровне 4-х метров от земли, бочка на "будке", в будке ардуина. То есть кабель идет из "будки" до верха бочки и опускается обратно, но уже в бочке. "Рабочий ход" примерно 1,3 метра (бочка не наполняется под срез и не высасывается досуха.
Шина i2c не предназначена для работы на длинных линиях, это внутриплатная шина. Тебе надо врЕзать в бок бочки внизу датчик давления и поставить там Тиньку + JDY-40 или RS-485. Если просыпаться раз в 10сек. одного заряда 18650 хватить на сезон с запасом.
Привет. Вижу несколько вариантов. Первые два, как ты хочешь - повозиться:
1) Попробовать витую пару вместо телефонного кабеля причем линию данных пустить именно через скрученную пару. Установить доп. конденсатор по питанию датчика микрофарад на 100. Дописать алгоритм "Долбления" датчика пока не будет результата. Питание датчика через пин ардуино для возможности принудительного отключения/включения питания. Не факт что поможет. Также любая дырочка в кабеле приведет к затоплению датчика. Кабель нужен хороший с экранирующей оплеткой.
2) Поставить ардуино нано в презерватив с датчиком и передавать данные на наружную ардуино например по протоколу One-wire.
3) Сделать штуцер на бочке внизу куда прикрутить датчик давления, предназначенный для этого, а там хоть радиоканал с батарейным питанием. Не прослужит долго презерватив и рано или поздно кабель потечет, а он как трубка, все вниз польется. Можно посмотреть в сторону автомобильных датчиков давления, можно специализированные глянуть. Цены не кусаются в 5-10$ думаю возможно вложиться.
Буду смотреть в сторону поплавка с магнитом на трубе. В трубу засуну цепочку резисторов с герконами. Будет сильно дискретно, но точнее 10 градаций в принципе и не надо.
Про герметичность. Сейчас в воде, но думал поднять датчик выше уровня воды в трубе с открытым низом и герметичным верхом. Тогда давление в трубе будет то же, но датчик будет уже не в воде. Заглушенная канализационная труба с резинкой, щедро смазанной силиконом, вполне держит. Сложнее обеспечить герметичный вывод провода, без утечек воздуха по изоляции.
Слушай, Prostovova а если сверху датчик расстояния приколхозить? Чем дальше поверхность жидкости или поплавка тем меньше уровень. Варианты: GY-530, VL53L0X, HC-SR04, JSN-SR04T
Я думал в этом направлении
Как поведет себя ультразвук в железной бочке неизвестно
лазер - то же не понятно. От воды неизвестно как отразится. От "поплавка" - тоже не все стабильно: переменное освещение, "поплавок" не должен уходить в сторону, наклоняться и т.д. Например лазер GY-530 не вдохновил стабильной работой. Хотя по правде я его в других целях тестировал. Может и вариант по физике, но по интерфейсу он же тот же I2C
"бочка" - это параллелепипед примерно 2м*1,5м в плане высотой 1,5м. Доступ - люк 50см*50см в углу
Слушай, Prostovova а если сверху датчик расстояния приколхозить? Чем дальше поверхность жидкости или поплавка тем меньше уровень. Варианты: GY-530, VL53L0X, HC-SR04, JSN-SR04T
так вроде не более пары недель назад кто-то уже приходил с вопросом, на что поменять датчик HC-SR04 в бочке. а то он гниет буквально за пару месяцев
Может кто из гуру подскажет...
Но, помоему, какая -то мудренная схема подключения у Вас..
1. Всегда подключал датчик BME280 без подтягивающих резисторов и конденсаторов, т.к. это все дело есть в плате датчика (стабилизатор напряжения), к примеру вид подключения датчика bmp180 http://adatum.ru/podklyuchenie-tsifrovogo-barometra-bmp180-k-arduino.html
2. Прошивку в формате hex, вряд ли кто то будет ковырять, а вот скетч, в формате ino, могли бы посмотреть.
3. Попробуйте подключить один датчик bme 280 без всяких прибамбасов, залить тестовый скетч и проверить показания датчика в мониторе порта, к примеру...
#include <Wire.h> #define BME280_ADDRESS 0x76 unsigned long int hum_raw,temp_raw,pres_raw; signed long int t_fine; uint16_t dig_T1; int16_t dig_T2; int16_t dig_T3; uint16_t dig_P1; int16_t dig_P2; int16_t dig_P3; int16_t dig_P4; int16_t dig_P5; int16_t dig_P6; int16_t dig_P7; int16_t dig_P8; int16_t dig_P9; int8_t dig_H1; int16_t dig_H2; int8_t dig_H3; int16_t dig_H4; int16_t dig_H5; int8_t dig_H6; void setup() { uint8_t osrs_t = 1; //Temperature oversampling x 1 uint8_t osrs_p = 1; //Pressure oversampling x 1 uint8_t osrs_h = 1; //Humidity oversampling x 1 uint8_t mode = 3; //Normal mode uint8_t t_sb = 5; //Tstandby 1000ms uint8_t filter = 0; //Filter off uint8_t spi3w_en = 0; //3-wire SPI Disable uint8_t ctrl_meas_reg = (osrs_t << 5) | (osrs_p << 2) | mode; uint8_t config_reg = (t_sb << 5) | (filter << 2) | spi3w_en; uint8_t ctrl_hum_reg = osrs_h; Serial.begin(9600); Wire.begin(); writeReg(0xF2,ctrl_hum_reg); writeReg(0xF4,ctrl_meas_reg); writeReg(0xF5,config_reg); readTrim(); // } void loop() { double temp_act = 0.0, press_act = 0.0,hum_act=0.0; signed long int temp_cal; unsigned long int press_cal,hum_cal; readData(); temp_cal = calibration_T(temp_raw); press_cal = calibration_P(pres_raw); hum_cal = calibration_H(hum_raw); temp_act = (double)temp_cal / 100.0; press_act = (double)press_cal / 100.0; hum_act = (double)hum_cal / 1024.0; Serial.print("TEMP : "); Serial.print(temp_act); Serial.print(" DegC PRESS : "); Serial.print(press_act); Serial.print(" hPa HUM : "); Serial.print(hum_act); Serial.println(" %"); delay(1000); } void readTrim() { uint8_t data[32],i=0; Wire.beginTransmission(BME280_ADDRESS); Wire.write(0x88); Wire.endTransmission(); Wire.requestFrom(BME280_ADDRESS,24); while(Wire.available()){ data[i] = Wire.read(); i++; } Wire.beginTransmission(BME280_ADDRESS); Wire.write(0xA1); Wire.endTransmission(); Wire.requestFrom(BME280_ADDRESS,1); data[i] = Wire.read(); i++; Wire.beginTransmission(BME280_ADDRESS); Wire.write(0xE1); Wire.endTransmission(); Wire.requestFrom(BME280_ADDRESS,7); while(Wire.available()){ data[i] = Wire.read(); i++; } dig_T1 = (data[1] << 8) | data[0]; dig_T2 = (data[3] << 8) | data[2]; dig_T3 = (data[5] << 8) | data[4]; dig_P1 = (data[7] << 8) | data[6]; dig_P2 = (data[9] << 8) | data[8]; dig_P3 = (data[11]<< 8) | data[10]; dig_P4 = (data[13]<< 8) | data[12]; dig_P5 = (data[15]<< 8) | data[14]; dig_P6 = (data[17]<< 8) | data[16]; dig_P7 = (data[19]<< 8) | data[18]; dig_P8 = (data[21]<< 8) | data[20]; dig_P9 = (data[23]<< 8) | data[22]; dig_H1 = data[24]; dig_H2 = (data[26]<< 8) | data[25]; dig_H3 = data[27]; dig_H4 = (data[28]<< 4) | (0x0F & data[29]); dig_H5 = (data[30] << 4) | ((data[29] >> 4) & 0x0F); dig_H6 = data[31]; } void writeReg(uint8_t reg_address, uint8_t data) { Wire.beginTransmission(BME280_ADDRESS); Wire.write(reg_address); Wire.write(data); Wire.endTransmission(); } void readData() { int i = 0; uint32_t data[8]; Wire.beginTransmission(BME280_ADDRESS); Wire.write(0xF7); Wire.endTransmission(); Wire.requestFrom(BME280_ADDRESS,8); while(Wire.available()){ data[i] = Wire.read(); i++; } pres_raw = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4); temp_raw = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4); hum_raw = (data[6] << 8) | data[7]; } signed long int calibration_T(signed long int adc_T) { signed long int var1, var2, T; var1 = ((((adc_T >> 3) - ((signed long int)dig_T1<<1))) * ((signed long int)dig_T2)) >> 11; var2 = (((((adc_T >> 4) - ((signed long int)dig_T1)) * ((adc_T>>4) - ((signed long int)dig_T1))) >> 12) * ((signed long int)dig_T3)) >> 14; t_fine = var1 + var2; T = (t_fine * 5 + 128) >> 8; return T; } unsigned long int calibration_P(signed long int adc_P) { signed long int var1, var2; unsigned long int P; var1 = (((signed long int)t_fine)>>1) - (signed long int)64000; var2 = (((var1>>2) * (var1>>2)) >> 11) * ((signed long int)dig_P6); var2 = var2 + ((var1*((signed long int)dig_P5))<<1); var2 = (var2>>2)+(((signed long int)dig_P4)<<16); var1 = (((dig_P3 * (((var1>>2)*(var1>>2)) >> 13)) >>3) + ((((signed long int)dig_P2) * var1)>>1))>>18; var1 = ((((32768+var1))*((signed long int)dig_P1))>>15); if (var1 == 0) { return 0; } P = (((unsigned long int)(((signed long int)1048576)-adc_P)-(var2>>12)))*3125; if(P<0x80000000) { P = (P << 1) / ((unsigned long int) var1); } else { P = (P / (unsigned long int)var1) * 2; } var1 = (((signed long int)dig_P9) * ((signed long int)(((P>>3) * (P>>3))>>13)))>>12; var2 = (((signed long int)(P>>2)) * ((signed long int)dig_P8))>>13; P = (unsigned long int)((signed long int)P + ((var1 + var2 + dig_P7) >> 4)); return P; } unsigned long int calibration_H(signed long int adc_H) { signed long int v_x1; v_x1 = (t_fine - ((signed long int)76800)); v_x1 = (((((adc_H << 14) -(((signed long int)dig_H4) << 20) - (((signed long int)dig_H5) * v_x1)) + ((signed long int)16384)) >> 15) * (((((((v_x1 * ((signed long int)dig_H6)) >> 10) * (((v_x1 * ((signed long int)dig_H3)) >> 11) + ((signed long int) 32768))) >> 10) + (( signed long int)2097152)) * ((signed long int) dig_H2) + 8192) >> 14)); v_x1 = (v_x1 - (((((v_x1 >> 15) * (v_x1 >> 15)) >> 7) * ((signed long int)dig_H1)) >> 4)); v_x1 = (v_x1 < 0 ? 0 : v_x1); v_x1 = (v_x1 > 419430400 ? 419430400 : v_x1); return (unsigned long int)(v_x1 >> 12); }1. Про защиту от осадков пока вопос открытый пока использую просто пластиковый контейнер с мелкими дырочками для вентиляции. Насекомых думаю не стоит особо опасаться. Особенно на 6-м этаже. У нас их тут в принципе мало.
2. Схему подключения нарисовал. Правда в библиотеке не было моего модуля. Поставил какой был. У меня такой. На нём явно есть стабилизатор. Значит питать можно от 5 вольт. Скетч прилагаю.
3. Провода обычные... Для макетки. Вот фото в сборе.
4. Вообще конечно погрешность грустная. Вряд ли такой модуль подходит для уличного термометра...
Я извиняюсь, а не подскажете скетч у Вас в чём?
Просто как то привык что скетч идёт с .ino на конце.
P.S. из архива распаковал.
Я извиняюсь, а не подскажете скетч у Вас в чём?
Просто как то привык что скетч идёт с .ino на конце.
P.S. из архива распаковал.
Этот скетч я делал для PlatformIO. Довольно удобная среда для программирования. Ardiuino IDE как IDE всё-таки совершено убог. Где-то в прошлом веке остался. Примерно в его начале
1. Всегда подключал датчик BME280 без подтягивающих резисторов и конденсаторов, т.к. это все дело есть в плате датчика (стабилизатор напряжения), к примеру вид подключения датчика bmp180 http://adatum.ru/podklyuchenie-tsifrovogo-barometra-bmp180-k-arduino.html
2. Прошивку в формате hex, вряд ли кто то будет ковырять, а вот скетч, в формате ino, могли бы посмотреть.
1. Попробую без подтягивающих сопротивлений.
2. А где hex? Я выложил чистый С++
Ну и потом. Разве может помешать кондесатор на питании? Подтягивающие резисторы на шине i2c? Какое они могут оказать влияние на измерения датчика? Что даст проверка показаний в мониторе порта? Показания идут. С этим проблем нет. Вопрос в том как проверить их правильность?
Ну и потом. Разве может помешать кондесатор на питании? Подтягивающие резисторы на шине i2c? Какое они могут оказать влияние на измерения датчика? Что даст проверка показаний в мониторе порта? Показания идут. С этим проблем нет. Вопрос в том как проверить их правильность?
Вот Вы и проверьте, с показаниями обычного ртутного термометра...
1. Всегда подключал датчик BME280 без подтягивающих резисторов и конденсаторов, т.к. это все дело есть в плате датчика (стабилизатор напряжения), к примеру вид подключения датчика bmp180 http://adatum.ru/podklyuchenie-tsifrovogo-barometra-bmp180-k-arduino.html
2. Прошивку в формате hex, вряд ли кто то будет ковырять, а вот скетч, в формате ino, могли бы посмотреть.
1. Попробую без подтягивающих сопротивлений.
2. А где hex? Я выложил чистый С++
В архиве, в папке , у меня такой путь, C:\Users\Комп\Downloads\radio_3\radio_3\.pioenvs\nanoatmega328\firmware.hex
Ну, Вы знаете, людям свойственно приписывать всему старому самые замечательные свойства :)
Если бы Вы часто бывали на хоккейных стадионах и были бы примерно моего возрата, то наверняка согласились бы с моим мнением: "Вот лет сорок назад ... и лёд блестел ярче, и шайбы лучше скользили, и девки на трибунах пофигуристее были" :)
Ностальгия - признак молодости
С температурой все понятно, а вот как проверить правильность показания влажности... У меня три латчика, правдва все китайские, показывают три разных значения :)
В архиве, в папке , у меня такой путь, C:\Users\Комп\Downloads\radio_3\radio_3\.pioenvs\nanoatmega328\firmware.hex
То есть вы полагаете, что проблема в библиотеке?
С температурой все понятно, а вот как проверить правильность показания влажности... У меня три латчика, правдва все китайские, показывают три разных значения :)
У разных датчиков - разная погрешность и диапазон измерений...
Как вариант, узнайте телефон местной (городской) метеостанции, запросите у них значения относительной влажности для вашего населенного пункта и проведите замеры относительной влажности рядом с вашей метеостанцией...
В архиве, в папке , у меня такой путь, C:\Users\Комп\Downloads\radio_3\radio_3\.pioenvs\nanoatmega328\firmware.hex
То есть вы полагаете, что проблема в библиотеке?
Я собственно, не Гуру, а новичок в данной области.
Просто, если Вы выложите конкректный скетч в формате ino, шансы, что Вам помогут возрастают...
Просто, если Вы выложите конкректный скетч в формате ino, шансы, что Вам помогут возрастают...
Переконвертировал в ino :)
Ваш скетч
#include <Wire.h> #include <Adafruit_Sensor.h> #include <Adafruit_BME280.h> #include <printf.h> #include <nRF24L01.h> #include <RF24.h> #include <RF24_config.h> #include <AM2320.h> #include "LED.h" Adafruit_BME280 bme; AM2320 am2320; #define DHT_INTERVAL_CHECK 10000 #define DHT_RESPONSE_OK 1 #define DHT_RESPONSE_ERROR 0 #define MODULE_ID 0x04 #define SENSOR1_ID 14 #define SENSOR1_TYPE 0x01 #define SENSOR2_ID 15 #define SENSOR2_TYPE 0x02 #define SENSOR3_ID 16 #define SENSOR3_TYPE 0x03 #define SENSOR4_ID 19 #define SENSOR4_TYPE 0x01 #define SENSOR5_ID 20 #define SENSOR5_TYPE 0x02 #define RADIO_INTERVAL 100 struct sensor_data { unsigned char sensor_id; unsigned char sensor_type; unsigned short value; }; struct message_header { unsigned char module_id; unsigned char message_number; unsigned char message_type; unsigned char crc; unsigned long timestamp; }; struct message { struct message_header header; struct sensor_data sensors[6]; }; struct meteo_info { unsigned long time; byte state; float temperature; float humidity; float temperature2; float humidity2; float pressure; }; struct meteo_info info; unsigned long lastReadTime = 0; unsigned long now = 0; unsigned char message_num = 0; unsigned long checkInterval = DHT_INTERVAL_CHECK; #define BUFFER_SIZE 32 RF24 radio(9, 10); unsigned char buffer[BUFFER_SIZE]; const uint64_t pipe = 0x0601170001LL; unsigned long restart_time = 0; unsigned long last_sent_time = 0; unsigned int radio_error_counter = 0; LED led_power(2); LED led_send(3); LED led_error(4); int pinDebug = 5; bool debugMode = false; const unsigned char crc8Table[256] = { 0x00, 0x31, 0x62, 0x53, 0xC4, 0xF5, 0xA6, 0x97, 0xB9, 0x88, 0xDB, 0xEA, 0x7D, 0x4C, 0x1F, 0x2E, 0x43, 0x72, 0x21, 0x10, 0x87, 0xB6, 0xE5, 0xD4, 0xFA, 0xCB, 0x98, 0xA9, 0x3E, 0x0F, 0x5C, 0x6D, 0x86, 0xB7, 0xE4, 0xD5, 0x42, 0x73, 0x20, 0x11, 0x3F, 0x0E, 0x5D, 0x6C, 0xFB, 0xCA, 0x99, 0xA8, 0xC5, 0xF4, 0xA7, 0x96, 0x01, 0x30, 0x63, 0x52, 0x7C, 0x4D, 0x1E, 0x2F, 0xB8, 0x89, 0xDA, 0xEB, 0x3D, 0x0C, 0x5F, 0x6E, 0xF9, 0xC8, 0x9B, 0xAA, 0x84, 0xB5, 0xE6, 0xD7, 0x40, 0x71, 0x22, 0x13, 0x7E, 0x4F, 0x1C, 0x2D, 0xBA, 0x8B, 0xD8, 0xE9, 0xC7, 0xF6, 0xA5, 0x94, 0x03, 0x32, 0x61, 0x50, 0xBB, 0x8A, 0xD9, 0xE8, 0x7F, 0x4E, 0x1D, 0x2C, 0x02, 0x33, 0x60, 0x51, 0xC6, 0xF7, 0xA4, 0x95, 0xF8, 0xC9, 0x9A, 0xAB, 0x3C, 0x0D, 0x5E, 0x6F, 0x41, 0x70, 0x23, 0x12, 0x85, 0xB4, 0xE7, 0xD6, 0x7A, 0x4B, 0x18, 0x29, 0xBE, 0x8F, 0xDC, 0xED, 0xC3, 0xF2, 0xA1, 0x90, 0x07, 0x36, 0x65, 0x54, 0x39, 0x08, 0x5B, 0x6A, 0xFD, 0xCC, 0x9F, 0xAE, 0x80, 0xB1, 0xE2, 0xD3, 0x44, 0x75, 0x26, 0x17, 0xFC, 0xCD, 0x9E, 0xAF, 0x38, 0x09, 0x5A, 0x6B, 0x45, 0x74, 0x27, 0x16, 0x81, 0xB0, 0xE3, 0xD2, 0xBF, 0x8E, 0xDD, 0xEC, 0x7B, 0x4A, 0x19, 0x28, 0x06, 0x37, 0x64, 0x55, 0xC2, 0xF3, 0xA0, 0x91, 0x47, 0x76, 0x25, 0x14, 0x83, 0xB2, 0xE1, 0xD0, 0xFE, 0xCF, 0x9C, 0xAD, 0x3A, 0x0B, 0x58, 0x69, 0x04, 0x35, 0x66, 0x57, 0xC0, 0xF1, 0xA2, 0x93, 0xBD, 0x8C, 0xDF, 0xEE, 0x79, 0x48, 0x1B, 0x2A, 0xC1, 0xF0, 0xA3, 0x92, 0x05, 0x34, 0x67, 0x56, 0x78, 0x49, 0x1A, 0x2B, 0xBC, 0x8D, 0xDE, 0xEF, 0x82, 0xB3, 0xE0, 0xD1, 0x46, 0x77, 0x24, 0x15, 0x3B, 0x0A, 0x59, 0x68, 0xFF, 0xCE, 0x9D, 0xAC }; unsigned char crc8(struct message *pmessage) { unsigned char *pcBlock = (unsigned char *)(void *)pmessage; unsigned char len = sizeof(*pmessage); unsigned char crc = 0xFF; for (int i = 0; i < len; i++) { unsigned char b = *pcBlock++; if (i == 3) b = 0; crc = crc8Table[crc ^ b]; } return crc; } void setup_radio() { if (::debugMode) { return; } radio.begin(); radio.setChannel(1); radio.setPALevel(RF24_PA_MAX); radio.setDataRate(RF24_2MBPS); radio.setAutoAck(1); radio.setRetries(15,15); radio.setCRCLength(RF24_CRC_16); radio.openWritingPipe(pipe); // Open the default reading and writing pipe radio.powerUp(); radio.startListening(); radio.stopListening(); radio.printDetails(); ::restart_time = millis(); ::radio_error_counter = 0; } void setup() { Serial.begin(115200); printf_begin(); Serial.print(F("Meteo module ")); Serial.println (MODULE_ID); pinMode(pinDebug, OUTPUT); digitalWrite (pinDebug, LOW); pinMode(pinDebug, INPUT); if (digitalRead(pinDebug) == HIGH) { ::debugMode = true; Serial.println (F("Debug mode ON!")); led_error.on(); ::checkInterval = 1000; } while (!bme.begin(0x76)) { Serial.println(F("Could not find a valid BME280 sensor, check wiring!")); delay(500); } setup_radio(); led_power.blink(250); ::info.state = DHT_RESPONSE_ERROR; Serial.println(); } void printValues(); void prepareDate() { if (::debugMode) { return; } memset(&buffer, 0, BUFFER_SIZE); struct message * pmessage = (struct message *)(void *)&buffer; pmessage->header.module_id = MODULE_ID; pmessage->header.message_number = ::message_num; //pmessage->header.message_type = MESSAGE_TYPE_BROADCAST; pmessage->header.timestamp = info.time; pmessage->sensors[0].sensor_id = SENSOR1_ID; pmessage->sensors[0].sensor_type = SENSOR1_TYPE; pmessage->sensors[0].value = (unsigned short)((info.temperature + 100) * 10); pmessage->sensors[1].sensor_id = SENSOR2_ID; pmessage->sensors[1].sensor_type = SENSOR2_TYPE; pmessage->sensors[1].value = (unsigned short)(info.humidity * 10); pmessage->sensors[2].sensor_id = SENSOR3_ID; pmessage->sensors[2].sensor_type = SENSOR3_TYPE; pmessage->sensors[2].value = (unsigned short)((info.pressure - 650) * 100); pmessage->sensors[3].sensor_id = SENSOR4_ID; pmessage->sensors[3].sensor_type = SENSOR4_TYPE; pmessage->sensors[3].value = (unsigned short)((info.temperature2 + 100) * 10); pmessage->sensors[4].sensor_id = SENSOR5_ID; pmessage->sensors[4].sensor_type = SENSOR5_TYPE; pmessage->sensors[4].value = (unsigned short)(info.humidity2 * 10); pmessage->header.crc = crc8(pmessage); } void checkTemperature() { bool allOk = true; float t = bme.readTemperature(); float h = bme.readHumidity(); float p = bme.readPressure(); if (isnan(t) || isnan(h) || isnan(p)) { allOk = false; } else if (t < -100.0) { allOk = false; } else { ::info.time = ::now; ::info.state = DHT_RESPONSE_OK; ::info.temperature = t - 1.5; ::info.humidity = h; ::info.pressure = p * 0.0075; } switch(am2320.Read()) { case 2: Serial.println("CRC failed"); allOk = false; break; case 1: Serial.println("Sensor offline"); allOk = false; break; case 0: ::info.temperature2 = am2320.t; ::info.humidity2 = am2320.h; break; } if (allOk) { printValues(); prepareDate(); //sendDate(::info); ::lastReadTime = now; } } void printValues() { Serial.print("Temperature = "); Serial.print(::info.temperature); Serial.print(" *C; "); Serial.print(::info.temperature2); Serial.println(" *C"); Serial.print("Pressure = "); Serial.print(::info.pressure); Serial.println(" mm"); Serial.print("Humidity = "); Serial.print(::info.humidity); Serial.print(" %; "); Serial.print(::info.humidity2); Serial.println(" %"); Serial.println(); } void sendMessage() { int retry = 0; bool ok = false; do { ok = radio.write(&buffer, BUFFER_SIZE); if (!ok) { led_send.off(); led_error.flash(30); ::radio_error_counter++; //printf("Error send!!!\n"); } else { led_send.flash(30); led_error.off(); radio_error_counter = 0; break; } if (--retry <= 0) { ok = true; } delay(50); } while(!ok); message_num++; } void sendDate(struct meteo_info info) { if (::info.state != DHT_RESPONSE_OK) return; led_send.on(); sendMessage(); ::last_sent_time = ::now; led_send.off(); } void checkRadio() { if (::debugMode) { return; } if (last_sent_time + RADIO_INTERVAL < ::now) { sendDate(::info); } if (::radio_error_counter > 0) { printf("Radio error count = %i\n", ::radio_error_counter); if (::radio_error_counter > 10) { setup_radio(); } } } void loop() { led_power.touch(); led_error.touch(); ::now = millis(); if (::now - ::lastReadTime >= checkInterval) { //printValues(); checkTemperature(); ::lastReadTime = now; } checkRadio(); }а может кто выручит калибровочными константами и сырыми данными с ацп BME280
Калибровочные для каждого экземпляра свои, на заводе прописываются. Что вы будете с чужими-то делать?
ну разумеется подсуну в свой код для проверки работоспособности.
есть сомнения что датчик живой, люди пишут что такое часто случается.
константы и выхлоп
7036 66A9 0032
8E1C D5FE 0BD0 1910 FFF5 FFF9 300C D120 1388
00 018A 00 290F 0329 1E
00087829 0005788D 00003051
00087808 00057880 00003551
000877ED 0005786A 0000F550
000877CC 0005785C 0000DD50
000877B5 00057866 0000C150
000877AC 00057876 0000C950
0008778D 00057844 0000BB50
00087759 0005782D 00009E50
00087746 0005780D 0000B150
00087733 0005784B 0000BE50
и вот что получается, с моими константами датчик не может работать в принципе
сырые данные ацп - влажность
0xDB02 1.013
0xFFFE 60.002
а вот с константами из инета, в диапазон укладывается
0x4C6B 1.006
0x8F74 99.996
dig_H1 = 0x4B
dig_H2 = 0x0171
dig_H3 = 0x00
dig_H4 = 0x012F
dig_H5 = 0x0000
dig_H6 = 0x1E
Может кому пригодится опрос BME BMP280 без библиотеки. Писал на скорость опроса для метеостанции в автономной работе
// Всегда мерять сначала температуру, потом остальное т.к. температура запоминается и влияет на давление и влажность. //Время на измерение всех трех показателей около 20 мс. #define BME280 0x60 #include <Wire.h> int32_t t_fine;//служебная переменная struct { //Структура, рекомендую хранить в RTC памяти и пользоваться при просыпании uint32_t crc32; // калибровочные биты uint16_t dig_T1; int16_t dig_T2, dig_T3;//температура uint16_t dig_P1; int16_t dig_P2, dig_P3, dig_P4, dig_P5, dig_P6, dig_P7, dig_P8, dig_P9;//давление uint8_t dig_H1, dig_H3; int16_t dig_H2, dig_H4, dig_H5; int8_t dig_H6;//влажность //прочитанный chip_id uint8_t chip_id; } rtcData; void setup() { pinMode(12, OUTPUT); digitalWrite(12, HIGH); //d6 пока что сюда подключен датчик, позже отключу Serial.begin(115200); Wire.begin(); if (!BMxbegin()) {ESP.restart();}// настраиваем датчик. если датчик не подключен то перезагружаемся. Рекомендую настраивать при первом запуске и не отключать питание на время сна Serial.print("\n\nchip_id: 0x"); Serial.println(rtcData.chip_id, HEX); // printCalibData(); } void loop() { Serial.println(); startMeasurement(); if (measureOk())// если измерение проведено то читаем данные. Тут идет проверка и ожидание готовности датчика до 25 мс { Serial.println(readTemperature()); Serial.println(readPressure() / 100.0F); if (rtcData.chip_id == BME280) Serial.println(readHumidity()); } else { Serial.println("Measure timeout"); } delay (1000); } // дальше код рекомендую в отдельную вкладку вставить void setRegister(uint8_t reg, const uint8_t value) { Wire.beginTransmission(0x76); Wire.write(reg); Wire.write(value); Wire.endTransmission(true); } int32_t getRegister(uint8_t reg, uint8_t len) { if (len<1 || len>4) return NAN; Wire.beginTransmission(0x76); Wire.write(reg); Wire.endTransmission(false); Wire.requestFrom(0x76, len, true); int32_t value = 0; for (byte i = 0; i < len; i++) { value <<= 8; value |= (uint8_t)Wire.read(); } Wire.endTransmission(true); return value; } bool BMxbegin(){ rtcData.chip_id = (uint8_t)getRegister(0xD0, 1); if (rtcData.chip_id < 0x56 || rtcData.chip_id > 0x60 || rtcData.chip_id == 0x59) {return 0;} // если датчик не обнаружен то перезагружаемся if (rtcData.chip_id == BME280) setRegister(0xF2, B00000001);//Измерять влажность если BME setRegister(0xF5, B11100000);// измерение раз в 4 сек(оно отключено в 0хF4) и фильтрация по 4м измерениям getCalibData(); return 1; } void getCalibData() { // читаю калибровочные биты Wire.beginTransmission(0x76); Wire.write(0x88); Wire.endTransmission(false); Wire.requestFrom(0x76, 26, true); rtcData.dig_T1 = Wire.read() | (Wire.read() << 8); //88/89 rtcData.dig_T2 = Wire.read() | (Wire.read() << 8); //8A/8B rtcData.dig_T3 = Wire.read() | (Wire.read() << 8); //8C/8D rtcData.dig_P1 = Wire.read() | (Wire.read() << 8); //8E/8F rtcData.dig_P2 = Wire.read() | (Wire.read() << 8); //90/91 rtcData.dig_P3 = Wire.read() | (Wire.read() << 8); //92/93 rtcData.dig_P4 = Wire.read() | (Wire.read() << 8); //94/95 rtcData.dig_P5 = Wire.read() | (Wire.read() << 8); //96/97 rtcData.dig_P6 = Wire.read() | (Wire.read() << 8); //98/99 rtcData.dig_P7 = Wire.read() | (Wire.read() << 8); //9A/9B rtcData.dig_P8 = Wire.read() | (Wire.read() << 8); //9C/9D rtcData.dig_P9 = Wire.read() | (Wire.read() << 8); //9E/9F Wire.read();// A0 пропускаю rtcData.dig_H1 = Wire.read(); //A1 Wire.beginTransmission(0x76); Wire.write(0xE1); Wire.endTransmission(false); Wire.requestFrom(0x76, 7, true); rtcData.dig_H2 = Wire.read() | Wire.read() << 8; //E1/E2 rtcData.dig_H3 = Wire.read(); //E3 rtcData.dig_H4 |= Wire.read() << 4; //E4 { uint8_t E5; E5 |= Wire.read(); //E5 rtcData.dig_H4 |= E5 & 0b00000111; rtcData.dig_H5 |= ((E5 & 0b11110000) >> 4) | (Wire.read() << 4); } //E6 rtcData.dig_H6 |= Wire.read(); //E7 } void printCalibData() { Serial.println F("---------Temp----------"); Serial.println(rtcData.dig_T1, HEX); Serial.println(rtcData.dig_T2, HEX); Serial.println(rtcData.dig_T3, HEX); Serial.println F("---------Pres----------"); Serial.println(rtcData.dig_P1, HEX); Serial.println(rtcData.dig_P2, HEX); Serial.println(rtcData.dig_P3, HEX); Serial.println(rtcData.dig_P4, HEX); Serial.println(rtcData.dig_P5, HEX); Serial.println(rtcData.dig_P6, HEX); Serial.println(rtcData.dig_P7, HEX); Serial.println(rtcData.dig_P8, HEX); Serial.println(rtcData.dig_P9, HEX); Serial.println("-----------Hum-----------"); Serial.println(rtcData.dig_H1, HEX); Serial.println(rtcData.dig_H2, HEX); Serial.println(rtcData.dig_H3, HEX); Serial.println(rtcData.dig_H4, HEX); Serial.println(rtcData.dig_H5, HEX); Serial.println(rtcData.dig_H6, HEX); Serial.println("------------------------"); } void startMeasurement(){ setRegister(0xF4, B01001101);//Запуск измерения температуры и давления//010(17бит температура)011(18бит давление)01(однократное измерение и переход в спячку 00)//было 10110111 } bool measureOk() { // Ждем окончания измерений uint32_t lastmillis = millis(); while (getRegister (0xF3, 1) & 0b00001001) { if (millis() - lastmillis > 25) return 0;// стандартное время измерений 16мс даем 25 на всякий случай } return 1; } float readTemperature() { // читаю значение АЦП BMx int32_t adc_T = (uint32_t)getRegister(0xFA, 3); adc_T >>= 4; // младший регистр содержит только 4 бита. Сдвигаем все данные на 4 бита //Расчет по даташиту float var1 = ((((adc_T >> 3) - ((int32_t)rtcData.dig_T1 << 1))) * ((int32_t)rtcData.dig_T2)) >> 11; float var2 = (((((adc_T >> 4) - ((int32_t)rtcData.dig_T1)) * ((adc_T >> 4) - ((int32_t)rtcData.dig_T1))) >> 12) * ((int32_t)rtcData.dig_T3)) >> 14; t_fine = var1 + var2 ; float T = (t_fine * 5 + 128) >> 8; return T / 100; } float readPressure() { int64_t var1, var2, p; int32_t adc_P = getRegister(0xF7, 3); if (adc_P == 0x800000) // value in case pressure measurement was disabled return NAN; adc_P >>= 4; var1 = ((int64_t)t_fine) - 128000; var2 = var1 * var1 * (int64_t)rtcData.dig_P6; var2 = var2 + ((var1 * (int64_t)rtcData.dig_P5) << 17); var2 = var2 + (((int64_t)rtcData.dig_P4) << 35); var1 = ((var1 * var1 * (int64_t)rtcData.dig_P3) >> 8) + ((var1 * (int64_t)rtcData.dig_P2) << 12); var1 = (((((int64_t)1) << 47) + var1)) * ((int64_t)rtcData.dig_P1) >> 33; if (var1 == 0) return 0; // avoid exception caused by division by zero p = 1048576 - adc_P; p = (((p << 31) - var2) * 3125) / var1; var1 = (((int64_t)rtcData.dig_P9) * (p >> 13) * (p >> 13)) >> 25; var2 = (((int64_t)rtcData.dig_P8) * p) >> 19; p = ((p + var1 + var2) >> 8) + (((int64_t)rtcData.dig_P7) << 4); return (float)p / 256; } float readHumidity() { while (getRegister (0xF3, 1) & 0b00001001) {} int32_t adc_H = getRegister(0xFD, 2); if (adc_H == 0x8000) return NAN;// value in case humidity measurement was disabled int32_t v_x1_u32r; v_x1_u32r = (t_fine - ((int32_t)76800)); v_x1_u32r = (((((adc_H << 14) - (((int32_t)rtcData.dig_H4) << 20) - (((int32_t)rtcData.dig_H5) * v_x1_u32r)) + ((int32_t)16384)) >> 15) * (((((((v_x1_u32r * ((int32_t)rtcData.dig_H6)) >> 10) * (((v_x1_u32r * ((int32_t)rtcData.dig_H3)) >> 11) + ((int32_t)32768))) >> 10) + ((int32_t)2097152)) * ((int32_t)rtcData.dig_H2) + 8192) >> 14)); v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * ((int32_t)rtcData.dig_H1)) >> 4)); v_x1_u32r = (v_x1_u32r < 0) ? 0 : v_x1_u32r; v_x1_u32r = (v_x1_u32r > 419430400) ? 419430400 : v_x1_u32r; float h = (v_x1_u32r >> 12); return h / 1024.0; }ужос...
я смотрю, работать с массивами вы так и не научились...
Согласен, вы смотрите.
Типы разные в масив научите запихивать, будут масивы.
По делу будут предложения?
Согласен, вы смотрите.
Типы разные в масив научите запихивать, будут масивы.
По делу будут предложения?
Вы все равно с этими "разными типами" работаете в коде как с непрерывным байтовым массивом. Тасуете их туда-сюда, преобразуете по своей прихоти то в 32битный лонг. то в 64-битный лонг лонг. Ну и какй смысл был давать этим полям отдельные названия? - зададли бы непрерывный массив да и все
И что помешало в строчках 82-93 всю структуру прочитать по i2c одним блоком?
Ты думаешь, такой код
053if(1<len>4)returnNAN;будет кто-то всерьёз рассматривать?
А разве код выложен для предложений?
Мне казалось, что он выложен на тот случай, если
Ну, пусть себе лежит, может кому и пригодится.
А предложений, вроде, никто не запрашивал :-)
И что помешало в строчках 82-93 всю структуру прочитать по i2c одним блоком?
Тут прокол, верно.
А в целом - код есть калька с Адафруитовской библиотеки, там такая же акробатика с преобразованиями типов.
массив структур?
Вы все равно с этими "разными типами" работаете в коде как с непрерывным байтовым массивом. Тасуете их туда-сюда, преобразуете по своей прихоти то в 32битный лонг. то в 64-битный лонг лонг
Это по делу написано. Не получается у меня одним циклом в масив все прочесть. Если меняю типы данных dig_P1..dig_P9 на uint16_t..int16_t..uint32_t..int32_t, не трогая основной код, то получаю неверный результат давления
Например dig_P2 при неверном типе печатается в сериал как D668 а при верном как FFFFD668. Тут я и не соображу почему FFFF добавляется. Конечно было бы проще в один масив считать все и сразу. Знаю что это можно сделать для dig_P2..dig_P9.
массив структур?
Пока не дорос до них. Нужно изучать.
p-a-h-a, дык может и не стоит велосипед изобретать? Смотрю код, много лет гуляющий по сети, ну очень похож...
Подскажите плз
С этими датчиками, на длинной линии желательны подтягивающие резисторы.
На какой стороне их правильнее ставить? На стороне датчика или на стороне ардуины?
PS
так получилось, что использован именно такой датчик и именно на длинной линии. Кабель - не помню, как называется, но просто тонкий четырех проводный (типа телефонного). Система постоянно сбоит. Однократно, при перезагрузке по питанию, считывает, а потом начинает врать. При стендировании, в лабораторных условиях, на том же кабеле, все работало без сбоев.
Коротко проект такой - датчик в презервативе - помещается на дно бочки и по давлению считается заполненность бочки. Есть кнопка обнуления (можно поднять датчик на поверхность, сбросить показания и считать их за Ноль. Верхний срез бочки примерно на уровне 4-х метров от земли, бочка на "будке", в будке ардуина. То есть кабель идет из "будки" до верха бочки и опускается обратно, но уже в бочке. "Рабочий ход" примерно 1,3 метра (бочка не наполняется под срез и не высасывается досуха.
Шина i2c не предназначена для работы на длинных линиях, это внутриплатная шина. Тебе надо врЕзать в бок бочки внизу датчик давления и поставить там Тиньку + JDY-40 или RS-485. Если просыпаться раз в 10сек. одного заряда 18650 хватить на сезон с запасом.
Привет. Вижу несколько вариантов. Первые два, как ты хочешь - повозиться:
1) Попробовать витую пару вместо телефонного кабеля причем линию данных пустить именно через скрученную пару. Установить доп. конденсатор по питанию датчика микрофарад на 100. Дописать алгоритм "Долбления" датчика пока не будет результата. Питание датчика через пин ардуино для возможности принудительного отключения/включения питания. Не факт что поможет. Также любая дырочка в кабеле приведет к затоплению датчика. Кабель нужен хороший с экранирующей оплеткой.
2) Поставить ардуино нано в презерватив с датчиком и передавать данные на наружную ардуино например по протоколу One-wire.
3) Сделать штуцер на бочке внизу куда прикрутить датчик давления, предназначенный для этого, а там хоть радиоканал с батарейным питанием. Не прослужит долго презерватив и рано или поздно кабель потечет, а он как трубка, все вниз польется. Можно посмотреть в сторону автомобильных датчиков давления, можно специализированные глянуть. Цены не кусаются в 5-10$ думаю возможно вложиться.
Эх-хе-хе-хе-хе
А поначалу идея казалась неплохой.
Буду смотреть в сторону поплавка с магнитом на трубе. В трубу засуну цепочку резисторов с герконами. Будет сильно дискретно, но точнее 10 градаций в принципе и не надо.
Про герметичность. Сейчас в воде, но думал поднять датчик выше уровня воды в трубе с открытым низом и герметичным верхом. Тогда давление в трубе будет то же, но датчик будет уже не в воде. Заглушенная канализационная труба с резинкой, щедро смазанной силиконом, вполне держит. Сложнее обеспечить герметичный вывод провода, без утечек воздуха по изоляции.
Спасибо за советы. JDY-40 то же поизучаю.
Слушай, Prostovova а если сверху датчик расстояния приколхозить? Чем дальше поверхность жидкости или поплавка тем меньше уровень. Варианты: GY-530, VL53L0X, HC-SR04, JSN-SR04T
https://www.youtube.com/watch?v=q4x6ypaXGf8&ab_channel=ArduinoProm
https://youtu.be/TiVjCRc9-60?t=317
Я думал в этом направлении
Как поведет себя ультразвук в железной бочке неизвестно
лазер - то же не понятно. От воды неизвестно как отразится. От "поплавка" - тоже не все стабильно: переменное освещение, "поплавок" не должен уходить в сторону, наклоняться и т.д. Например лазер GY-530 не вдохновил стабильной работой. Хотя по правде я его в других целях тестировал. Может и вариант по физике, но по интерфейсу он же тот же I2C
"бочка" - это параллелепипед примерно 2м*1,5м в плане высотой 1,5м. Доступ - люк 50см*50см в углу
Слушай, Prostovova а если сверху датчик расстояния приколхозить? Чем дальше поверхность жидкости или поплавка тем меньше уровень. Варианты: GY-530, VL53L0X, HC-SR04, JSN-SR04T
так вроде не более пары недель назад кто-то уже приходил с вопросом, на что поменять датчик HC-SR04 в бочке. а то он гниет буквально за пару месяцев