Ну не знаю неделю дождь льёт рядом с датчиком. Показания влажности в такой период 98-99%. Считаю идеальным калибром. В другие периоды очень сложно найти от чего мерять влажность. Хотя в летние месяцы при полностью открытых окнах домашние показания и уличные условно одинаковые. Сама станция стоит близко к открытому окну за которым датчик
А откуда инфа что должно что-то покрывать поверхность электродов. Не видел не разу не окислов не другого налёта. Возможно я живу в довольно таки чистом месте. Думаю что датчику в районе МКАДа действительно несладко. Но внутри датчика всё таки замкнутая система
Притом что большинство орегоновских датчиков имеют заявленный диапазон измеренией как 25%...95%, 98 это странное число )
Этот датчик с полосками имеет покрытие, по факту это конденсатор электрический, он считывается глючным способом по таблицам, если его потереть - показания сбиваются, а спиртом протереть - так и вообще перестанет работать.
Ну про "у всех" это вы загнули, это у тех что за $0.5-$1 нет. У всяких Si4432, CC1101 она, насколько я помню, есть.
И кстати ещё. Подскажите, где почитать на тему исправления показаний влажности орегоновских датчиков? У меня все три из разных серий, все сейчас за бортом и при -9С все показывают 40-50%, что явно враньё.
Орегоновские датчики это те еще поделки, да))) на датчик влажности я бы вообще внимания не обращал, врет он безбожно!
Недавно сравнивал показания с цифровым и довольно точным SHT21 (Typ. Humidity Accuracy %RH ±2, Typ. Temperature °C ±0.3), орегон внутри показывал 18%, SHT 30%, снаружи 45%, SHT 68%
и не надейтесь, разброс показаний влажности у SHT21 тоже весьма велик порой бывает. ;) у меня их несколько, и сравнивал с экземпляром у коллеги, лежащие рядом иной раз до 10% разницу показывают.
и не надейтесь, разброс показаний влажности у SHT21 тоже весьма велик порой бывает. ;) у меня их несколько, и сравнивал с экземпляром у коллеги, лежащие рядом иной раз до 10% разницу показывают.
10% это не в полтора раза как сейчас, уже жить можно :)
в любом случае SHT21 это цифра и более точен по определению, дальше уже только профессиональные решения идут типа Honeywell и подобных, но там ценник уже другой будет...
спасибо, классно работает а для отладки можно вывести на экран количество потерянных "периодов приёма данных". чтобы понять там ли стоит приемник. ещё с вашим кодом работает thgn800.
а можно при допустим 5 пропущеных периодах выводить звёздочку(допустим), при десяти пропущеных писать данные устарели. и ещё на экране 1602 вполне можно уместить данные с 2 датчиков ещё и место останется. чтобы показания не скакали надо для каждого датчика свой (data) иметь? тут можно подсказать что исправить
почему для приёма сигнала от орегоновских датчиков мы используем всякие китайские супергетородины и прочую муть?
В смысле этот вопрос?...
Потому что Si4432 по умолчанию не умеет принимать ничего ) его надо для этого программировать, а простые приёмники вроде тех что на первой странице - питание подключил и они сразу начинают данные выдавать.
Потому что Si4432 по умолчанию не умеет принимать ничего ) его надо для этого программировать, а простые приёмники вроде тех что на первой странице - питание подключил и они сразу начинают данные выдавать.
Они же выдают не данные, а сырой шум. А si4432 способен сам поймать, распотрошить посылку, посчитать CRC и выдать уже приготовленные данные с гарниром. Цена-то у всех приёмников копеечная.
а можно при допустим 5 пропущеных периодах выводить звёздочку(допустим), при десяти пропущеных писать данные устарели. и ещё на экране 1602 вполне можно уместить данные с 2 датчиков ещё и место останется. чтобы показания не скакали надо для каждого датчика свой (data) иметь? тут можно подсказать что исправить
Всё можно сделать, было бы желание )
Я бы сделал массивы для каждого параметра, и хранил данные там, типа:
float t[5]; // температура
byte h[5]; // влажность
byte b[5]; // батарейка
unsigned long upd[5]; // время
byte ch=0; // счётчик
В качестве индекса использовал бы номер канала channel(data), а в upd[] сохранял бы время последнего прихода пакета
спасибо попытаюсь, код для меня очень длинный смогу ли осилить... в посту#180 у меня уличный датчик работает почти без пропусков. в вашем же коде мне кажется присутствует ошибка. сначала принимает показания обеих датчиков, однако спустя пару часов уличный датчик пропадает из сериал, появляется 1 раз на 20(примерно) показаний "комнатного" и даже реже. возможно чтото с эфиром, но живу в довольно таки чистом месте(электромагнитном)
И что с ним не так я не знаю... у меня он работает вполне стабильно.
Опять же не забывайте, что в тот самый момент пока ардуина выводит данные в экран или печатает в сериал, эфир сканироваться перестаёт... ардуино не многозадачная, пришедшая посылка не будет принята. Вполне допускаю что происходит циклическое вхождение в "резонанс" с передатчиком.
Орегоны передают данные с разной задержкой, именно по этой причине, на первом канале каждые 39 секунд, на втором канале 41 секунду, на третьем канале 43 секунды. Мне кажется это сделано чтоб если вдруг они все вместе захотят передать данные в один и тот же момент времени, на следующий раз у них бы это не получилось ))
Так же вполне допускаю, что на этой частоте в эфире вещается что-то, что мешает приёму. Или у вас там просто датчик неисправен, как у меня номер два.
Вот график обновлений данных моих Орегон датчиков, второй (зелёный) часто глючит сам по себе. Иногда может сам по себе часами ничего якобы не слать... Хотя первый и третий стабильны. 4-й это передатчик собранный на Ардуино, на 5-й не обращайте внимания, это тестовый.
Тогда бы это была бы тема программирования si4432, а не Arduino ;)
Там не программирование, а конфигурирование. Один раз забил данные в регистры и всё. Нельзя же, например, назвать программированием LCD2004 забивку туда пользовательских символов.
Тогда бы это была бы тема программирования si4432, а не Arduino ;)
Там не программирование, а конфигурирование. Один раз забил данные в регистры и всё. Нельзя же, например, назвать программированием LCD2004 забивку туда пользовательских символов.
Все так, но скетч явно сложнее будет, пока не видел проектов где есть связка SI4432 и Oregon или RCSwitch.
В целом конечно чип более навороченный и недорогой.
Хочется предупредить желающих повторить конструкцию что схема из ардуино и датчика rf-5v(у меня) очень требовательна к питанию. сначала думал что помехи в эфире мешают принимать датчику сигналы, однако выяснилось, что если питать ардуино напряжением с компьютера, то наблюдается интересная картина. если компьютер в простое то не наблюдается ничего ненормального, если же запустить игру, то видимо возникает большое количество помех в кабеле юсб и данные в ардуино перестают приходить. само расположение всех элементов конструкции не менясь. просадок в питании не наблюдается бп с запасом стоит
5) И самое главное - найти осциллографом или методом научного тыка временные интервалы для "TIME = 482". У меня три ардуины и у всех этот параметр пришлось подбирать индивидуально, из-за различий в работе внутреннего таймера. Приём на базе работает только если это время +/- 1-3 микросекунды от стандарта. Выключение прерываний сильно влияет на этот параметр, если их не выключать ардуина растягивает пакеты во времени на произвольное число и они не всегда понимаются базой. Если нет осциллографа можно попробовать перебрать по очереди все значения от 480-490... ;)
А не могли бы вы рабочий код целиком привести?
Поправил по данной инструкции, но в консоли видно, что контрольная сумма всегда нули.
Соответственно, оригинальная погодная станция его не видит.
Поправил по данной инструкции, но в консоли видно, что контрольная сумма всегда нули.
Вы где-то ошиблись значит, проверьте что у вас вызывается именно checkSumAndCRC функция, перед отправкой, а не какая-то другая.
#include <Wire.h> // must be incuded here so that Arduino library object file references work
#include <Adafruit_SleepyDog.h>
// HTU21
#include "Adafruit_HTU21DF.h"
Adafruit_HTU21DF htu = Adafruit_HTU21DF();
byte HT;
char params[255];
long sleepMS;
#define V_PIN A0
#define TX_PIN 4
const unsigned long TIME = 482;
const unsigned long TWOTIME = TIME*2;
#define SEND_HIGH() digitalWrite(TX_PIN, HIGH)
#define SEND_LOW() digitalWrite(TX_PIN, LOW)
byte OregonMessageBuffer[10];
/**
* \brief Send logical "0" over RF
* \details azero bit be represented by an off-to-on transition
* \ of the RF signal at the middle of a clock period.
* \ Remenber, the Oregon v2.1 protocol add an inverted bit first
*/
inline void sendZero(void)
{
SEND_HIGH();
delayMicroseconds(TIME);
SEND_LOW();
delayMicroseconds(TWOTIME);
SEND_HIGH();
delayMicroseconds(TIME);
}
/**
* \brief Send logical "1" over RF
* \details a one bit be represented by an on-to-off transition
* \ of the RF signal at the middle of a clock period.
* \ Remenber, the Oregon v2.1 protocol add an inverted bit first
*/
inline void sendOne(void)
{
SEND_LOW();
delayMicroseconds(TIME);
SEND_HIGH();
delayMicroseconds(TWOTIME);
SEND_LOW();
delayMicroseconds(TIME);
}
/**
* Send a bits quarter (4 bits = MSB from 8 bits value) over RF
*
* @param data Source data to process and sent
*/
/**
* \brief Send a bits quarter (4 bits = MSB from 8 bits value) over RF
* \param data Data to send
*/
inline void sendQuarterMSB(const byte data)
{
(bitRead(data, 4)) ? sendOne() : sendZero();
(bitRead(data, 5)) ? sendOne() : sendZero();
(bitRead(data, 6)) ? sendOne() : sendZero();
(bitRead(data, 7)) ? sendOne() : sendZero();
}
/**
* \brief Send a bits quarter (4 bits = LSB from 8 bits value) over RF
* \param data Data to send
*/
inline void sendQuarterLSB(const byte data)
{
(bitRead(data, 0)) ? sendOne() : sendZero();
(bitRead(data, 1)) ? sendOne() : sendZero();
(bitRead(data, 2)) ? sendOne() : sendZero();
(bitRead(data, 3)) ? sendOne() : sendZero();
}
/******************************************************************/
/******************************************************************/
/******************************************************************/
/**
* \brief Send a buffer over RF
* \param data Data to send
* \param size size of data to send
*/
void sendData(byte *data, byte size)
{
for(byte i = 0; i < size; ++i)
{
sendQuarterLSB(data[i]);
sendQuarterMSB(data[i]);
}
}
/**
* \brief Send an Oregon message
* \param data The Oregon message
*/
void sendOregon(byte *data, byte size)
{
cli();
sendPreamble();
//sendOne();
//sendSync();
sendData(data, size);
//sendPostamble();
sei();
}
/**
* \brief Send preamble
* \details The preamble consists of 16 "1" bits
*/
inline void sendPreamble(void)
{
byte PREAMBLE[]={0xFF,0xFF};
sendData(PREAMBLE, 2);
}
/**
* \brief Send postamble
* \details The postamble consists of 8 "0" bits
*/
inline void sendPostamble(void)
{
#ifdef THN132N
sendQuarterLSB(0x00);
#else
byte POSTAMBLE[]={0x00};
sendData(POSTAMBLE, 1);
#endif
}
/**
* \brief Send sync nibble
* \details The sync is 0xA. It is not use in this version since the sync nibble
* \ is include in the Oregon message to send.
*/
inline void sendSync(void)
{
sendQuarterLSB(0xA);
}
/******************************************************************/
/******************************************************************/
/******************************************************************/
/**
* \brief Set the sensor type
* \param data Oregon message
* \param type Sensor type
*/
inline void setType(byte *data, byte* type)
{
data[0] = type[0];
data[1] = type[1];
}
/**
* \brief Set the sensor channel
* \param data Oregon message
* \param channel Sensor channel (0x10, 0x20, 0x30)
*/
inline void setChannel(byte *data, byte channel)
{
data[2] = channel;
}
/**
* \brief Set the sensor ID
* \param data Oregon message
* \param ID Sensor unique ID
*/
inline void setId(byte *data, byte ID)
{
data[3] = ID;
}
/**
* \brief Set the sensor battery level
* \param data Oregon message
* \param level Battery level (0 = low, 1 = high)
*/
void setBatteryLevel(byte *data, byte level)
{
if(!level) data[4] = 0x0C;
else data[4] = level;
}
/**
* \brief Set the sensor temperature
* \param data Oregon message
* \param temp the temperature
*/
void setTemperature(byte *data, float temp)
{
// Set temperature sign
if(temp < 0)
{
data[6] = 0x08;
temp *= -1;
}
else
{
data[6] = 0x00;
}
int td = (int)temp / 10;
int tf = (int)temp % 10;
int tempFloat = (int)((temp * 10)) % 10;
// Set temperature decimal part
data[5] = (td << 4);
data[5] |= tf;
// Set temperature float part
data[4] |= (tempFloat << 4);
}
/**
* \brief Set the sensor humidity
* \param data Oregon message
* \param hum the humidity
*/
void setHumidity(byte* data, float hum)
{
int hd = (int)hum / 10;
int hf = (int)hum % 10;
int humFloat = (int)((hum * 10)) % 10;
data[7] = (humFloat<<4);
data[7] |= hd;
data[6] = (hf<<4);
}
/**
* \brief Sum data for checksum
* \param count number of bit to sum
* \param data Oregon message
*/
int Sum(byte count, const byte* data)
{
int s = 0;
for(byte i = 0; i<count;i++)
{
s += (data[i]&0xF0) >> 4;
s += (data[i]&0xF);
}
if(int(count) != count)
s += (data[count]&0xF0) >> 4;
return s;
}
/**
* \brief Calculate checksum
* \param data Oregon message
*/
void calculateAndSetChecksum(byte* data)
{
#ifdef THN132N
int s = ((Sum(6, data) + (data[6]&0xF) - 0xa) & 0xff);
data[6] |= (s&0x0F) << 4; data[7] = (s&0xF0) >> 4;
#else
data[8] = ((Sum(8, data) - 0xa) & 0xFF);
#endif
}
void checkSumAndCRC(byte * data, const uint8_t len)
{
#define mByte(i) (data[i])
#define NIBBLE(i) ((mByte(i>>1) >> (((i)&1)<<2))&0xf)
uint8_t i,j,c,CRC,SUM;
CRC =0x3C;
SUM =0x00;
uint8_t CCIT_POLY = 0x07;
for (j=1; j<2*len; j++)
{
c = NIBBLE(j);
SUM += c;
if ( j != 6 && j != 7){ // place for ID
CRC ^= c;
for(i = 0; i<4; i++)
if(CRC & 0x80 )
CRC = (CRC << 1) ^ CCIT_POLY;
else
CRC <<= 1;
CRC &= 0xff;
}
}
for(i = 0; i<4; i++)
if(CRC & 0x80 )
CRC = (CRC << 1) ^ CCIT_POLY;
else
CRC <<= 1;
data[len] = (SUM & 0xFF);
data[len+1] = CRC;
}
/******************************************************************/
////////////////////////////////////////////////////////////
void setup ()
{
Serial.begin(9600);
pinMode(V_PIN, INPUT);
pinMode(13, OUTPUT);
pinMode(TX_PIN, OUTPUT);
// randomSeed(analogRead(A0));
HT = htu.begin();
// Create the Oregon message for a temperature/humidity sensor
byte ID[] = {0x1A,0x2D};
setType(OregonMessageBuffer, ID);
setChannel(OregonMessageBuffer, 0x43);
setId(OregonMessageBuffer, 0xBB);
Serial.println("Start");
}
void loop()
{
while(millis()%1000!=500);
unsigned int val = analogRead(V_PIN);
float voltage = 5.0 / 1024 * val;
float htu_t = 0;
float htu_h = 0;
// Get temperature and humidity level from sensors
if(HT){
htu_t = htu.readTemperature();
// htu_h = htu.readHumidity();
htu_h = htu.readHumidity() + (25 - htu_t) * -0.15;
}
// Get battery
byte bt = ( voltage - 3.2) * 100 ;
setBatteryLevel(OregonMessageBuffer, round(bt/10.0) );
setTemperature(OregonMessageBuffer, (round(htu_t*10)/10.0) );
setHumidity(OregonMessageBuffer, (round(htu_h*10)/10.0) );
// Calculate the checksum
//calculateAndSetChecksum(OregonMessageBuffer);
checkSumAndCRC(OregonMessageBuffer,8);
Serial.print(millis()/1000.,3);
Serial.print(" ");
// Show the Oregon Message
for (byte i = 0; i < sizeof(OregonMessageBuffer); ++i) {
Serial.print(OregonMessageBuffer[i] >> 4, HEX);
Serial.print(OregonMessageBuffer[i] & 0x0F, HEX);
}
Serial.println();
digitalWrite(13,HIGH);
// Send the Message over RF
sendOregon(OregonMessageBuffer, sizeof(OregonMessageBuffer));
SEND_LOW();
delayMicroseconds(TWOTIME*10);
sendOregon(OregonMessageBuffer, sizeof(OregonMessageBuffer));
SEND_LOW();
digitalWrite(13,LOW);
Serial.print(htu_t,2);
Serial.print(",");
Serial.print(htu_h,2);
Serial.print(",");
Serial.print(voltage,3);
Serial.print(",");
Serial.println(bt);
/* Wire.begin();
Wire.beginTransmission(HTU21DF_I2CADDR);
Wire.write(HTU21DF_WRITEREG);
Wire.write(0x3);
Wire.endTransmission();
*/
delay(100);
// power save mode
sleepMS = Watchdog.sleep(8000);
sleepMS += Watchdog.sleep(8000);
sleepMS += Watchdog.sleep(8000);
sleepMS += Watchdog.sleep(8000);
sleepMS += Watchdog.sleep(8000);
sleepMS += Watchdog.sleep(4000);
}
Arduino nano с передатчиком и термо-гигро сенсором HTU21. Запитано от двух литиевых аккумуляторов 18650, с которых через делитель на резисторах считывается уровень напряжения. К сожалению, даже используя powesave-mode аккумуляторы приходится заряжать каждые две недели. Ардуина в sleep-mode потребляет ~7мА (наверное из-за светодиода, надо бы его отпаять...)
Подскажите пожалуйста, как можно реализовать вывод на LCD так, чтобы при любых значениях температуры, Цельсий всегда был в одном месте, и лишь отступ после "=" увеличивался или уменьшался.
Ничего нового для себя я в этом ролике не открыл. Как с помощью модуля передавать СВОИ данные - и так понятно. Мне пока не до конца ясно, как приспособить si4432 под протокол Орегона, возложив на чип всю обработку пакета. Может надо не вино с сыром, а водку с солёным огурцом попробовать в поисках ответа?
ну ладно вам, ну расслабился человек, что случилось то. а зачем на si4432 перекладывать обработку. а просто приём обеспечить? а что ардуино будет делать тогда? если обеспечить хороший приём то ардуино контрольную сумму то посчитает как нибудь сам
Хотя бы затем, что он это может. Пусть сам отлавливает преамбулу, синхропоследовательность и считает CRC. А уж чем нагрузить ардуино - найти можно. Тому же esp8266 это бы сильно облегчило жизнь.
ну ладно вам, ну расслабился человек, что случилось то.
Да задел за очень больное место. Сыр российский для него нормальный! Уж два года как за нормальным сыром в Финляндию ездить приходится. Извиняюсь за оффтоп :)
К сожалению, даже используя powesave-mode аккумуляторы приходится заряжать каждые две недели. Ардуина в sleep-mode потребляет ~7мА (наверное из-за светодиода, надо бы его отпаять...)
Когда мне надо было экономить, я тоже голову ломал, потом, оказалось, что стабилизатор на плате ест, и светодиод - было всё удалено, перешиты фьюзы для работы до 2.8v, и всё наладилось, и потребляла она во сне какие-то микроамперы.
Тут частота 8MHz (вместо 16) и не используется кварц (думал ещё сэкономить, но во сне роли не играет), и напряжение до 0v (т.е. при любом напряжении 0-5v будет работать, ну пока питания хватит):
Как мне реализовать вывод на экран LCD 2004, часов с DS3231 и значение давления с BMP280.
В какое место в скетче мне нужно "вставить" вывод на LCD эти данные?
lcd.setCursor(0,0);
lcd.print(time.gettime("H:i")); // выводим время
lcd.setCursor(10,0);
lcd.print(bme.readPressure()/133.3," mmHg"); // выводим давление
Если я их добавляю в "void loop ()" то перестают работать датчики Oregon
Если я добавляю там же, где и вывод информации с датчиков Oregon, то соответственно часы и давление обновляется на экране только тогда, когда приходят показания с датчиков Oregon.
// ATmega 2560
// Приёмник подключается к PWM(2)
// "LCD 2004", "DS3231", "BMP280" подключаются: SCL -> SCL(21); SDA -> SDA(20)
#define PORT 2
#define printByte(args) write(args);
#define BMP_SCK 13
#define BMP_MISO 12
#define BMP_MOSI 11
#define BMP_CS 10
#include <iarduino_RTC.h>
#include <Adafruit_BMP280.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
iarduino_RTC time(RTC_DS3231);
LiquidCrystal_I2C lcd(0x27,20,4); // Адрес моего "LCD 2004" 0x27, "LCD 1602" 0x3f
Adafruit_BMP280 bme; // работаем по шине I2C
uint8_t cels[8] = {0x2,0x5,0x5,0x2}; // Значёк цельсия
uint8_t batlow[8] = {0xE,0x1f,0x0,0x11,0x0,0x11,0x0,0x1f}; // Значок пустой батарейки
uint8_t batok[8] = {0xE,0x1f,0x11,0x15,0x15,0x15,0x11,0x1f}; // Значок полной батарейки
uint8_t termom1[8] = {0x4,0xA,0xE,0xE,0xE,0x1f,0x1f,0xE}; // Значок термометра больше 0
uint8_t termom0[8] = {0x4,0xA,0xA,0xA,0xE,0x1f,0x1f,0xE}; // Значок термометра меньше 0
uint8_t kapla[8] = {0x4,0x4,0xA,0xA,0x11,0x11,0x11,0xE}; // Значок капли
class DecodeOOK {
protected:
byte total_bits, bits, flip, state, pos, data[25];
virtual char decode (word width) =0;
public:
enum { UNKNOWN, T0, T1, T2, T3, OK, DONE };
DecodeOOK () { resetDecoder(); }
bool nextPulse (word width) {
if (state != DONE)
switch (decode(width)) {
case -1: resetDecoder(); break;
case 1: done(); break;
}
return isDone();
}
bool isDone () const { return state == DONE; }
const byte* getData (byte& count) const {
count = pos;
return data;
}
void resetDecoder () {
total_bits = bits = pos = flip = 0;
state = UNKNOWN;
}
// add one bit to the packet data buffer
virtual void gotBit (char value) {
total_bits++;
byte *ptr = data + pos;
*ptr = (*ptr >> 1) | (value << 7);
if (++bits >= 8) {
bits = 0;
if (++pos >= sizeof data) {
resetDecoder();
return;
}
}
state = OK;
}
// store a bit using Manchester encoding
void manchester (char value) {
flip ^= value; // manchester code, long pulse flips the bit
gotBit(flip);
}
// move bits to the front so that all the bits are aligned to the end
void alignTail (byte max =0) {
// align bits
if (bits != 0) {
data[pos] >>= 8 - bits;
for (byte i = 0; i < pos; ++i)
data[i] = (data[i] >> bits) | (data[i+1] << (8 - bits));
bits = 0;
}
// optionally shift bytes down if there are too many of 'em
if (max > 0 && pos > max) {
byte n = pos - max;
pos = max;
for (byte i = 0; i < pos; ++i)
data[i] = data[i+n];
}
}
void reverseBits () {
for (byte i = 0; i < pos; ++i) {
byte b = data[i];
for (byte j = 0; j < 8; ++j) {
data[i] = (data[i] << 1) | (b & 1);
b >>= 1;
}
}
}
void reverseNibbles () {
for (byte i = 0; i < pos; ++i)
data[i] = (data[i] << 4) | (data[i] >> 4);
}
void done () {
while (bits)
gotBit(0); // padding
state = DONE;
}
};
// 433 MHz decoders
class OregonDecoderV2 : public DecodeOOK
{
public:
OregonDecoderV2() {}
// add one bit to the packet data buffer
virtual void gotBit (char value)
{
if(!(total_bits & 0x01))
{
data[pos] = (data[pos] >> 1) | (value ? 0x80 : 00);
}
total_bits++;
pos = total_bits >> 4;
if (pos >= sizeof data)
{
resetDecoder();
return;
}
state = OK;
}
virtual char decode(word width)
{
if (200 <= width && width < 1200)
{
byte w = width >= 700;
switch (state)
{
case UNKNOWN:
if (w != 0)
{
// Long pulse
++flip;
}
else if (w == 0 && 24 <= flip)
{
// Short pulse, start bit
flip = 0;
state = T0;
}
else
{
// Reset decoder
return -1;
}
break;
case OK:
if (w == 0)
{
// Short pulse
state = T0;
}
else
{
// Long pulse
manchester(1);
}
break;
case T0:
if (w == 0)
{
// Second short pulse
manchester(0);
}
else
{
// Reset decoder
return -1;
}
break;
}
}
else if (width >= 2500 && pos >= 8)
{
return 1;
}
else
{
return -1;
}
return 0;
}
};
class OregonDecoderV3 : public DecodeOOK {
public:
OregonDecoderV3() {}
// add one bit to the packet data buffer
virtual void gotBit (char value) {
data[pos] = (data[pos] >> 1) | (value ? 0x80 : 00);
total_bits++;
pos = total_bits >> 3;
if (pos >= sizeof data) {
resetDecoder();
return;
}
state = OK;
}
virtual char decode (word width) {
if (200 <= width && width < 1200) {
byte w = width >= 700;
switch (state) {
case UNKNOWN:
if (w == 0)
++flip;
else if (32 <= flip) {
flip = 1;
manchester(1);
} else
return -1;
break;
case OK:
if (w == 0)
state = T0;
else
manchester(1);
break;
case T0:
if (w == 0)
manchester(0);
else
return -1;
break;
}
} else {
return -1;
}
return total_bits == 80 ? 1: 0;
}
};
OregonDecoderV2 orscV2;
OregonDecoderV3 orscV3;
volatile word pulse;
void ext_int_1(void) {
static word last;
// determine the pulse length in microseconds, for either polarity
pulse = micros() - last;
last += pulse;
}
//
// Oregon packet decoder
//
float temperature(const byte* data)
{
int sign = (data[6]&0x8) ? -1 : 1;
float temp = ((data[5]&0xF0) >> 4)*10 + (data[5]&0xF) + (float)(((data[4]&0xF0) >> 4) / 10.0);
return sign * temp;
}
byte humidity(const byte* data)
{
return (data[7]&0xF) * 10 + ((data[6]&0xF0) >> 4) ;
}
float humi_ext(const byte* data)
{
return humidity(data) + ((data[7]&0xF0)>>4)/10.0 ;
}
byte battery(const byte* data)
{
return (data[4] & 0xF) ;
}
byte serial(const byte* data)
{
return (data[3]);
}
byte channel(const byte* data)
{
byte channel;
switch (data[2])
{
case 0x10:
channel = 1;
break;
case 0x20:
channel = 2;
break;
case 0x40:
channel = 3;
break;
case 0x13:
channel = 1;
break;
case 0x23:
channel = 2;
break;
case 0x33:
channel = 3;
break;
case 0x43:
channel = 4;
break;
case 0x53:
channel = 5;
break;
}
return channel;
}
int Sum(byte count, const byte* data)
{
int s = 0;
for(byte i = 0; i<count;i++)
{
s += (data[i]&0xF0) >> 4;
s += (data[i]&0xF);
}
if(int(count) != count)
s += (data[count]&0xF0) >> 4;
return s;
}
////////////////////////////////////////////////////
////////////////////////////////////////////////////
/////////// Вывод результата в Serial /////////////
////////////////////////////////////////////////////
////////////////////////////////////////////////////
void reportSerial (const char* s, class DecodeOOK& decoder){
byte pos;
const byte* data = decoder.getData(pos);
Serial.print(millis()/1000.,3);
Serial.print(" ");
Serial.print(s);
Serial.print(' ');
for (byte i = 0; i < pos; ++i) {
Serial.print(data[i] >> 4, HEX);
Serial.print(data[i] & 0x0F, HEX);
}
if( data[8] == (Sum(8,data)-0xa)&0xFF )
{
Serial.print(" Bat.: "+String(battery(data)));
Serial.print(" ID: "+String(serial(data),HEX));
Serial.println();
Serial.print("Ch."+String(channel(data)));
Serial.println();
Serial.print("T="+String(temperature(data),1)+"C"+" H="+String(humidity(data))+"%");
Serial.println();
if(battery(data) == 0xC){
Serial.print("Bat: LOW");
Serial.println();}
else {
Serial.print("Bat: OK");
Serial.println();}
}
else
{
int sum = ((Sum(6, data) + (data[6]&0xF) - 0xa) & 0xff);
if( (sum&0xF) == (data[6]>>4) && (sum>>4) == (data[7]&0xF) ){
Serial.print(" Bat: "+String(battery(data)));
Serial.print(" ID: "+String(serial(data),HEX));
Serial.println();
Serial.print("Ch."+String(channel(data)));
Serial.println();
Serial.print("T="+String(temperature(data),1)+"C");
Serial.println();
if (battery(data) == 0xC){
Serial.print("Bat: LOW");
Serial.println();
}
else {
Serial.print("Bat: OK");
Serial.println();
}
}
else
{
Serial.print(" Checksum error");
}
Serial.println();
}
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
/////////////////// Вывод результата на LCD /////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
/// Датчик с влажностью
if( data[8] == (Sum(8,data)-0xa)&0xFF )
{
if ((channel(data))==1|(channel(data))==3|(channel(data))==5) // Канал датчика 1, 3, 5
{
lcd.setCursor(0,1); lcd.print(" ");
lcd.setCursor(0,1);
lcd.print (channel(data));
lcd.print(" ");
if (temperature(data) < -9)
{
lcd.printByte(4);
lcd.setCursor(3,1);
lcd.print(String(temperature(data),1)); lcd.printByte(0); lcd.print("C");
}
if ((temperature(data) >= -9) & (temperature(data) < 0))
{
lcd.printByte(4);
lcd.setCursor(4,1);
lcd.print(String(temperature(data),1)); lcd.printByte(0); lcd.print("C");
}
if ((temperature(data) >= 0) & (temperature(data) <= 9))
{
lcd.printByte(3);
lcd.setCursor(5,1);
lcd.print(String(temperature(data),1)); lcd.printByte(0); lcd.print("C");
}
if (temperature(data) >= 10)
{
lcd.printByte(3);
lcd.setCursor(4,1);
lcd.print(String(temperature(data),1)); lcd.printByte(0); lcd.print("C");
}
lcd.setCursor(11,1);
lcd.printByte(5); lcd.print(String(humidity(data))+"%");
if( (battery(data)) == 0xC)
{
lcd.setCursor(16,1);
lcd.printByte(1);
}
else
{
lcd.setCursor(16,1);
lcd.printByte(2);
}
}
else // Канал датчика отличны от 1, 3, 5
{
lcd.setCursor(0,2); lcd.print(" ");
lcd.setCursor(0,2);
lcd.print (channel(data));
lcd.print(" ");
if (temperature(data) < -9)
{
lcd.printByte(4);
lcd.setCursor(3,2);
lcd.print(String(temperature(data),1)); lcd.printByte(0); lcd.print("C");
}
if ((temperature(data) >= -9) & (temperature(data) < 0))
{
lcd.printByte(4);
lcd.setCursor(4,2);
lcd.print(String(temperature(data),1)); lcd.printByte(0); lcd.print("C");
}
if ((temperature(data) >= 0) & (temperature(data) <= 9))
{
lcd.printByte(3);
lcd.setCursor(5,2);
lcd.print(String(temperature(data),1)); lcd.printByte(0); lcd.print("C");
}
if (temperature(data) >= 10)
{
lcd.printByte(3);
lcd.setCursor(4,2);
lcd.print(String(temperature(data),1)); lcd.printByte(0); lcd.print("C");
}
lcd.setCursor(11,2);
lcd.printByte(5); lcd.print(String(humidity(data))+"%");
if( (battery(data)) == 0xC)
{
lcd.setCursor(16,2);
lcd.printByte(1);
}
else
{
lcd.setCursor(16,2);
lcd.printByte(2);
}
}
}
/// Датчик без влажности
else
{
int sum = ((Sum(6, data) + (data[6]&0xF) - 0xa) & 0xff);
if( (sum&0xF) == (data[6]>>4) && (sum>>4) == (data[7]&0xF) )
{
if ((channel(data))==1|(channel(data))==3|(channel(data))==5) // Канал датчика 1, 3, 5
{
lcd.setCursor(0,1); lcd.print(" ");
lcd.setCursor(0,1);
lcd.print (channel(data));
lcd.print(" ");
if (temperature(data) < -9)
{
lcd.printByte(4);
lcd.setCursor(3,1);
lcd.print(String(temperature(data),1)); lcd.printByte(0); lcd.print("C");
}
if ((temperature(data) >= -9) & (temperature(data) < 0))
{
lcd.printByte(4);
lcd.setCursor(4,1);
lcd.print(String(temperature(data),1)); lcd.printByte(0); lcd.print("C");
}
if ((temperature(data) >= 0) & (temperature(data) <= 9))
{
lcd.printByte(3);
lcd.setCursor(5,1);
lcd.print(String(temperature(data),1)); lcd.printByte(0); lcd.print("C");
}
if (temperature(data) >= 10)
{
lcd.printByte(3);
lcd.setCursor(4,0);
lcd.print(String(temperature(data),1)); lcd.printByte(0); lcd.print("C");
}
if( (battery(data)) == 0xC)
{
lcd.setCursor(16,1);
lcd.printByte(1)
}
else
{
lcd.setCursor(16,1);
lcd.printByte(2);
}
}
else // Канал датчика отличны от 1, 3, 5
{
lcd.setCursor(0,2); lcd.print(" ");
lcd.setCursor(0,2);
lcd.print (channel(data));
lcd.print(" ");
if (temperature(data) < -9)
{
lcd.printByte(4);
lcd.setCursor(3,2);
lcd.print(String(temperature(data),1)); lcd.printByte(0); lcd.print("C");
}
if ((temperature(data) >= -9) & (temperature(data) < 0))
{
lcd.printByte(4);
lcd.setCursor(4,2);
lcd.print(String(temperature(data),1)); lcd.printByte(0); lcd.print("C");
}
if ((temperature(data) >= 0) & (temperature(data) <= 9))
{
lcd.printByte(3);
lcd.setCursor(5,2);
lcd.print(String(temperature(data),1)); lcd.printByte(0); lcd.print("C");
}
if (temperature(data) >= 10)
{
lcd.printByte(3);
lcd.setCursor(4,2);
lcd.print(String(temperature(data),1)); lcd.printByte(0); lcd.print("C");
}
if( (battery(data)) == 0xC)
{
lcd.setCursor(16,2);
lcd.printByte(1)}
else
{
lcd.setCursor(16,2);
lcd.printByte(2);
}
}
}
}
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
//////////////// Конец вывод результата на LCD //////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
decoder.resetDecoder();
}
void setup () {
lcd.init();
lcd.backlight();
lcd.createChar(0, cels);
lcd.createChar(1, batlow);
lcd.createChar(2, batok);
lcd.createChar(3, termom1);
lcd.createChar(4, termom0);
lcd.createChar(5, kapla);
Serial.begin(9600);
time.begin();
Serial.println("\n[ookDecoder]");
if (!bme.begin()) {
Serial.println("Could not find a valid BMP280 sensor, check wiring!");
while (1);
}
pinMode(PORT, INPUT); // use the AIO pin
attachInterrupt(digitalPinToInterrupt(PORT), ext_int_1, CHANGE);
}
void loop () {
static int i = 0;
cli();
word p = pulse;
pulse = 0;
sei();
//if (p != 0){ Serial.print(++i); Serial.print('\n');}
if (p != 0) {
if (orscV2.nextPulse(p))
reportSerial("OSV2", orscV2);
if (orscV3.nextPulse(p))
reportSerial("OSV3", orscV3);
}
}
Вывод на дисплей должен, безусловно, находиться в функции loop(), но вывод не нужно делать при каждом выполнении функции - это отнимает много времени, и контроллеру просто некогда заниматься расшифровкой сигнала с приёмника. Потому у Вас ничего и не работает. Осуществляйте вывод на дисплей хотя бы раз в несколько секунд и будет Вам счастье. Привязываться к выводу данных с датчиков не обязательно.
Вывод на дисплей должен, безусловно, находиться в функции loop(), но вывод не нужно делать при каждом выполнении функции - это отнимает много времени, и контроллеру просто некогда заниматься расшифровкой сигнала с приёмника. Потому у Вас ничего и не работает. Осуществляйте вывод на дисплей хотя бы раз в несколько секунд и будет Вам счастье. Привязываться к выводу данных с датчиков не обязательно.
Ну не знаю неделю дождь льёт рядом с датчиком. Показания влажности в такой период 98-99%. Считаю идеальным калибром. В другие периоды очень сложно найти от чего мерять влажность. Хотя в летние месяцы при полностью открытых окнах домашние показания и уличные условно одинаковые. Сама станция стоит близко к открытому окну за которым датчик
А откуда инфа что должно что-то покрывать поверхность электродов. Не видел не разу не окислов не другого налёта. Возможно я живу в довольно таки чистом месте. Думаю что датчику в районе МКАДа действительно несладко. Но внутри датчика всё таки замкнутая система
Притом что большинство орегоновских датчиков имеют заявленный диапазон измеренией как 25%...95%, 98 это странное число )
Этот датчик с полосками имеет покрытие, по факту это конденсатор электрический, он считывается глючным способом по таблицам, если его потереть - показания сбиваются, а спиртом протереть - так и вообще перестанет работать.
http://pokupandex.ru/aliexpress/1287/kalibrovka-izmeriteley-vlazhnosti-s-datchikom-hr202l.html
в этом диапазоне погрешность не превышает заявленной, а амс понимает 2-98%
датчик резистивный
Перестал передавать показания датчик Oregon RTGN318.
Подумал, что батарейка села, заменил, безрезультатно.
Мало того, с других датчиков сигнал стал плохо приходить, подумал что помехи посторонние какие то.
Вынул батарейку из этого не работающего датчика и с остальтных датчиков стали данные приходить хорошо.
Получается датчик умер, да ещё и эфир засорять стал.
Ну про "у всех" это вы загнули, это у тех что за $0.5-$1 нет. У всяких Si4432, CC1101 она, насколько я помню, есть.
И кстати ещё. Подскажите, где почитать на тему исправления показаний влажности орегоновских датчиков? У меня все три из разных серий, все сейчас за бортом и при -9С все показывают 40-50%, что явно враньё.
Орегоновские датчики это те еще поделки, да))) на датчик влажности я бы вообще внимания не обращал, врет он безбожно!
Недавно сравнивал показания с цифровым и довольно точным SHT21 (Typ. Humidity Accuracy %RH ±2, Typ. Temperature °C ±0.3), орегон внутри показывал 18%, SHT 30%, снаружи 45%, SHT 68%
4ishops,
и не надейтесь, разброс показаний влажности у SHT21 тоже весьма велик порой бывает. ;) у меня их несколько, и сравнивал с экземпляром у коллеги, лежащие рядом иной раз до 10% разницу показывают.
4ishops,
и не надейтесь, разброс показаний влажности у SHT21 тоже весьма велик порой бывает. ;) у меня их несколько, и сравнивал с экземпляром у коллеги, лежащие рядом иной раз до 10% разницу показывают.
10% это не в полтора раза как сейчас, уже жить можно :)
в любом случае SHT21 это цифра и более точен по определению, дальше уже только профессиональные решения идут типа Honeywell и подобных, но там ценник уже другой будет...
Работал у меня датчик работал, а потом с него приехало вот такое... )
И ведь контрольная сумма совпала... Кто-то мне в эфир нагадил, или датчик с ума сошёл?... ))
спасибо, классно работает а для отладки можно вывести на экран количество потерянных "периодов приёма данных". чтобы понять там ли стоит приемник. ещё с вашим кодом работает thgn800.
Вот только код канала не универсален получается, надо его как-то допилить... )
а на 1602 пишет: канал.22
22 это 0x34 в HEX, канал третий, используете код функции что я выше привел.
получилось вот так
а можно при допустим 5 пропущеных периодах выводить звёздочку(допустим), при десяти пропущеных писать данные устарели. и ещё на экране 1602 вполне можно уместить данные с 2 датчиков ещё и место останется. чтобы показания не скакали надо для каждого датчика свой (data) иметь? тут можно подсказать что исправить
И ведь контрольная сумма совпала... Кто-то мне в эфир нагадил, или датчик с ума сошёл?... ))
Ну так там метод расчёта контрольной суммы не выдерживает никакой критики. Вероятность ошибки достаточно высока. Неоднократно подобные пакеты ловил.
Кстати, мой вопрос по поводу использования si4432 для ловли сигналов от датчиков Oregon был проигнорирован. Я что-то неприличное спросил?
Подскажите, почему компилятор ругается на эту строчку?
у вас там буква 'с' русская ;)
почему для приёма сигнала от орегоновских датчиков мы используем всякие китайские супергетородины и прочую муть?
В смысле этот вопрос?...
Потому что Si4432 по умолчанию не умеет принимать ничего ) его надо для этого программировать, а простые приёмники вроде тех что на первой странице - питание подключил и они сразу начинают данные выдавать.
у вас там буква 'с' русская ;)
Вот блин, спасибо!!
Потому что Si4432 по умолчанию не умеет принимать ничего ) его надо для этого программировать, а простые приёмники вроде тех что на первой странице - питание подключил и они сразу начинают данные выдавать.
Они же выдают не данные, а сырой шум. А si4432 способен сам поймать, распотрошить посылку, посчитать CRC и выдать уже приготовленные данные с гарниром. Цена-то у всех приёмников копеечная.
получилось вот так
а можно при допустим 5 пропущеных периодах выводить звёздочку(допустим), при десяти пропущеных писать данные устарели. и ещё на экране 1602 вполне можно уместить данные с 2 датчиков ещё и место останется. чтобы показания не скакали надо для каждого датчика свой (data) иметь? тут можно подсказать что исправить
Всё можно сделать, было бы желание )
Я бы сделал массивы для каждого параметра, и хранил данные там, типа:
В качестве индекса использовал бы номер канала channel(data), а в upd[] сохранял бы время последнего прихода пакета
Организовал бы в loop() показ всех датчиков по очереди, каждую третью секунду, вроде:
А si4432 способен сам поймать, распотрошить посылку, посчитать CRC и выдать уже приготовленные данные с гарниром.
Тогда бы это была бы тема программирования si4432, а не Arduino ;)
спасибо попытаюсь, код для меня очень длинный смогу ли осилить... в посту#180 у меня уличный датчик работает почти без пропусков. в вашем же коде мне кажется присутствует ошибка. сначала принимает показания обеих датчиков, однако спустя пару часов уличный датчик пропадает из сериал, появляется 1 раз на 20(примерно) показаний "комнатного" и даже реже. возможно чтото с эфиром, но живу в довольно таки чистом месте(электромагнитном)
Дело в том, что это не мой код )
И что с ним не так я не знаю... у меня он работает вполне стабильно.
Опять же не забывайте, что в тот самый момент пока ардуина выводит данные в экран или печатает в сериал, эфир сканироваться перестаёт... ардуино не многозадачная, пришедшая посылка не будет принята. Вполне допускаю что происходит циклическое вхождение в "резонанс" с передатчиком.
Орегоны передают данные с разной задержкой, именно по этой причине, на первом канале каждые 39 секунд, на втором канале 41 секунду, на третьем канале 43 секунды. Мне кажется это сделано чтоб если вдруг они все вместе захотят передать данные в один и тот же момент времени, на следующий раз у них бы это не получилось ))
Так же вполне допускаю, что на этой частоте в эфире вещается что-то, что мешает приёму. Или у вас там просто датчик неисправен, как у меня номер два.
Вот график обновлений данных моих Орегон датчиков, второй (зелёный) часто глючит сам по себе. Иногда может сам по себе часами ничего якобы не слать... Хотя первый и третий стабильны. 4-й это передатчик собранный на Ардуино, на 5-й не обращайте внимания, это тестовый.
На графике это время от millis()%10000.
Тогда бы это была бы тема программирования si4432, а не Arduino ;)
Там не программирование, а конфигурирование. Один раз забил данные в регистры и всё. Нельзя же, например, назвать программированием LCD2004 забивку туда пользовательских символов.
Тогда бы это была бы тема программирования si4432, а не Arduino ;)
Там не программирование, а конфигурирование. Один раз забил данные в регистры и всё. Нельзя же, например, назвать программированием LCD2004 забивку туда пользовательских символов.
Все так, но скетч явно сложнее будет, пока не видел проектов где есть связка SI4432 и Oregon или RCSwitch.
В целом конечно чип более навороченный и недорогой.
На данный момент реализовал одновременный вывод информации с двух датчиков.
На первую строку выводятся данные с датчиков, чьи каналы 1,3,5, а на вторую соответственно 2,4,6.
Выводятся только текущие полученные значения, на матрицу и накопление данных моих знаний не достаточно.
Хочется предупредить желающих повторить конструкцию что схема из ардуино и датчика rf-5v(у меня) очень требовательна к питанию. сначала думал что помехи в эфире мешают принимать датчику сигналы, однако выяснилось, что если питать ардуино напряжением с компьютера, то наблюдается интересная картина. если компьютер в простое то не наблюдается ничего ненормального, если же запустить игру, то видимо возникает большое количество помех в кабеле юсб и данные в ардуино перестают приходить. само расположение всех элементов конструкции не менясь. просадок в питании не наблюдается бп с запасом стоит
В общем код из шапки поста неполный, надо его чуток дохачивать...
1) Кроме чексуммы восьмого байта ещё и CRC считать в девятом байте пакета.
Заменив старую функцию новой
2) Увеличить размер буфера с 9 на 10 из-за CRC.
3) Увеличить размер тишины между посылками delayMicroseconds(TWOTIME*10); хотя это и не обязательно, обычно база читает только первый посыл.
4) защитить код передатчика от прерываний
5) И самое главное - найти осциллографом или методом научного тыка временные интервалы для "TIME = 482". У меня три ардуины и у всех этот параметр пришлось подбирать индивидуально, из-за различий в работе внутреннего таймера. Приём на базе работает только если это время +/- 1-3 микросекунды от стандарта. Выключение прерываний сильно влияет на этот параметр, если их не выключать ардуина растягивает пакеты во времени на произвольное число и они не всегда понимаются базой. Если нет осциллографа можно попробовать перебрать по очереди все значения от 480-490... ;)
А не могли бы вы рабочий код целиком привести?
Поправил по данной инструкции, но в консоли видно, что контрольная сумма всегда нули.
Соответственно, оригинальная погодная станция его не видит.
Поправил по данной инструкции, но в консоли видно, что контрольная сумма всегда нули.
Вы где-то ошиблись значит, проверьте что у вас вызывается именно
checkSumAndCRC
функция, перед отправкой, а не какая-то другая.Arduino nano с передатчиком и термо-гигро сенсором HTU21. Запитано от двух литиевых аккумуляторов 18650, с которых через делитель на резисторах считывается уровень напряжения. К сожалению, даже используя powesave-mode аккумуляторы приходится заряжать каждые две недели. Ардуина в sleep-mode потребляет ~7мА (наверное из-за светодиода, надо бы его отпаять...)
Подскажите пожалуйста, как можно реализовать вывод на LCD так, чтобы при любых значениях температуры, Цельсий всегда был в одном месте, и лишь отступ после "=" увеличивался или уменьшался.
T=-25.5*C
T= 5.3*C
T= 25.2*C
Сейчас у меня так, "пляшет" от знака "=":
типа так надо
взято из другого места
https://www.youtube.com/watch?v=SbM9l1gNmB4 спрашивали про si4432. может поможет. кстати блогер Дмитрий Осипов просто отличный учитель в теме ардуино. классные обзоры
Ничего нового для себя я в этом ролике не открыл. Как с помощью модуля передавать СВОИ данные - и так понятно. Мне пока не до конца ясно, как приспособить si4432 под протокол Орегона, возложив на чип всю обработку пакета. Может надо не вино с сыром, а водку с солёным огурцом попробовать в поисках ответа?
ну ладно вам, ну расслабился человек, что случилось то. а зачем на si4432 перекладывать обработку. а просто приём обеспечить? а что ардуино будет делать тогда? если обеспечить хороший приём то ардуино контрольную сумму то посчитает как нибудь сам
а зачем на si4432 перекладывать обработку
Хотя бы затем, что он это может. Пусть сам отлавливает преамбулу, синхропоследовательность и считает CRC. А уж чем нагрузить ардуино - найти можно. Тому же esp8266 это бы сильно облегчило жизнь.
типа так надо
взято из другого места
Спасибо за совет.
Всё получилось.
ну ладно вам, ну расслабился человек, что случилось то.
Да задел за очень больное место. Сыр российский для него нормальный! Уж два года как за нормальным сыром в Финляндию ездить приходится. Извиняюсь за оффтоп :)
К сожалению, даже используя powesave-mode аккумуляторы приходится заряжать каждые две недели. Ардуина в sleep-mode потребляет ~7мА (наверное из-за светодиода, надо бы его отпаять...)
Когда мне надо было экономить, я тоже голову ломал, потом, оказалось, что стабилизатор на плате ест, и светодиод - было всё удалено, перешиты фьюзы для работы до 2.8v, и всё наладилось, и потребляла она во сне какие-то микроамперы.
"перешиты фьюзы" - а это как?
Прошил лоадер optiboot, и выставил фьюзы.
Тут частота 8MHz (вместо 16) и не используется кварц (думал ещё сэкономить, но во сне роли не играет), и напряжение до 0v (т.е. при любом напряжении 0-5v будет работать, ну пока питания хватит):
Тут 2.7v нижнее напряжение, с частотой 16MHz (остальные шил так, ниже 2.7 нет смысла работать, неустойчиво становится)
Тут обсуждалось, либо поищите тему про optiboot и сон.
Прошу помощи, совсем запутался.
Как мне реализовать вывод на экран LCD 2004, часов с DS3231 и значение давления с BMP280.
В какое место в скетче мне нужно "вставить" вывод на LCD эти данные?
lcd.setCursor(0,0);
lcd.print(time.gettime("H:i")); // выводим время
Вывод на дисплей должен, безусловно, находиться в функции loop(), но вывод не нужно делать при каждом выполнении функции - это отнимает много времени, и контроллеру просто некогда заниматься расшифровкой сигнала с приёмника. Потому у Вас ничего и не работает. Осуществляйте вывод на дисплей хотя бы раз в несколько секунд и будет Вам счастье. Привязываться к выводу данных с датчиков не обязательно.
Вывод на дисплей должен, безусловно, находиться в функции loop(), но вывод не нужно делать при каждом выполнении функции - это отнимает много времени, и контроллеру просто некогда заниматься расшифровкой сигнала с приёмника. Потому у Вас ничего и не работает. Осуществляйте вывод на дисплей хотя бы раз в несколько секунд и будет Вам счастье. Привязываться к выводу данных с датчиков не обязательно.
Спасибо за ответ, но что то у меня не работает.
А вот так всё работает:
Получилось так.
Код.
а вторая строчка что выводит?
а вторая строчка что выводит?
Номер канала>Время прихода данных
Спасибо за ответ, но что то у меня не работает.
Естественно не работает, была ночь и я жестоко ошибся. Надо было не
pora_vivodit > millis()
а
millis() >
pora_vivoditСпасибо за ответ, но что то у меня не работает.
Естественно не работает, была ночь и я жестоко ошибся. Надо было не
pora_vivodit > millis()
а
millis() >
pora_vivoditВас понял.
Но по сути, у меня работает похожее условие.
В вашем случае условие не выполнится, если в момент сравнения millis() вернёт не 10000, а например 10004.