Согласен, паять, мудрить с корпусом. В моём 3АА тоже хватит на год не меньше (10мА 0.5 секунды каждые 300 сек - просто чаще на народмон бессмысленно отправлять). Но суть в том, что я разочаровался в орегоне, в первую очередь из-за датчика влажности, а изначально я считал его примером, пока он у меня не появился. В самодельном можно использоать куда более интересные датчики, при этом используя минимум кода с обеих сторон, что позволяет мне запихнуть в одну мини.про кучу всего, а тут влезал только декодер и с трудом что-то ещё по мелочи совсем. Опять же расширяемость, сейчас у меня передаётся номер датчика, напряжение аккума, влажность и температура, можно же насобирать гораздо больше, из-за высокой частоты передачи можно использовать более мелкий корпус, и гораздо большее количество данных за единицу времени, с CRC и контролем получения посылки. Да и приёмник же Вы паятете всё равно, почему бы заодно не смаять передатчик? Тем более никаких подводных камней - датчик (4 провода), передатчик (6 проводов), батарейка (2 провода) ну и с платы отломать диоды и стабилизатор, чтоб не жрали, всё. И заодно никаких помех и соседей )
Ничего не имею против проекта, он интересен, и работает теперь у моей мамы ) Для меня данный код слишком сложен, поэтому суть в каких-то доработках приближался к нулю.
Всё же я собрал замену орегону, это оказалось куда проще, включая программу. Состоит из ардуины и nrf, ардуина и nrf24 ничего фактически не потребляют во сне, я их бужу раз в 5 минут, узнаю температуру, передаю, и отправляю в сон.
RF24 radio(9,10); //ce-9 ,csn-10
SI7021 si7021;
const uint32_t pipe = 000000042; // адрес тубы
int16_t datadat[5]={79, 0, 0, 0, 0}; //данные 0-"o" (79 - индикатор передающего), 1-ochan, 2-otemp, 3-ohum, 4-obat
float temp;
//=======================================================================================================
void setup() {
Serial.begin(9600); Serial.print ("...");
for (temp = 0; temp <= A5; temp++) // для экономии энергии кладём аналоговые выходы
{ pinMode (temp, OUTPUT); digitalWrite (temp, LOW); }
ADCSRA = 0; //для экономии энергии oтключаем ADC
si7021.initialize();
radio.begin();
radio.setRetries(15,15);
radio.setChannel(42); // Указываем канал передачи данных (от 0 до 127), 5 - значит передача данных осуществляется на частоте 2,405 ГГц (на одном канале может быть только 1 приёмник и до 6 передатчиков)
radio.setDataRate(RF24_250KBPS); // скорость обмена данными RF24_250KBPS, RF24_1MBPS или RF24_2MBPS
radio.setPALevel (RF24_PA_MAX); // Указываем мощность передатчика (RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_HIGH=-6dBm, RF24_PA_MAX=0dBm)
radio.openWritingPipe(pipe); // открыть канал на отправку
radio.openReadingPipe(1,pipe); // открыть канал на приём
radio.stopListening(); // приём остановить
delayMicroseconds(225);
#Serial.println ("...");
}
//=======================================================================================================
void loop() {
datadat[1]=3; //channel
si7021.getHumidity(temp); datadat[4]=temp*10; //влажность *10
si7021.getTemperature(temp); datadat[3]=temp*10; //температура *10
si7021.triggerMeasurement();
temp=(float)(1.1*16368)/Vbg(); datadat[2]=temp*100; //батарея *100
Serial.println ("");Serial.print("Chn:"); Serial.print(datadat[1]); Serial.print(" Bat:"); Serial.print(temp,3);
Serial.print(" To.txt="); Serial.print((datadat[3]/10)); Serial.print(" Ho.txt="); Serial.print(datadat[4]/10);
if (!radio.write(&datadat, sizeof(datadat))) Serial.println (" NoSend");
delay(200);
radio.powerDown(); //отключение радиомодуля
delay(200);
for (int i=0; i < 37; i++){ LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); } //сон 8x37 (300сек)
radio.powerUp(); //включение радиомодуля
delay(200);
}
//-------------------------------------------------------------------------------------------------------
int Vbg() {
ADMUX = (1<<REFS0)|(0<<REFS1)|(1<<MUX3)|(1<<MUX2)|(1<<MUX1)|(0<<MUX0);
long buffersamp=0;
for (int n=0x0; n<=0xff; n++ ) {
ADCSRA = 0xc7;
while (bit_is_set(ADCSRA,ADSC));
buffersamp += ADC; }
buffersamp >>=4; //16368 full scale 14bit
ADCSRA &= ~(1 << ADEN); // отключаем АЦП
return buffersamp;
}
С приёмником сложнее, т.к. 1ый приёмник у меня часы с фотки, они ловят показания, отображают на индикаторе и добавив свои измерения отправляют в прихожку на базу, но думаю будет понятно, всё подписано.
RF24 radio(9,10); //ce-9 ,csn-10
TM1637 disp(3,4); //clk 3, dio 4 - индикатор
SI7021 si7021;
int BMP085_ADDRESS = 0x77;
Adafruit_BMP085 bmp;
const uint32_t pipe=000000042;//адрес тубы
int16_t datadat[8]={73, 0, 0, 0, 0, 0, 0, 0}; //данные (кто передал 0-(79-Out, 73-In), 1-ochan, 2-bat, 3-temp, 4-ohum, 5-htemp, 6-hhum, 7-pressure
float temp;
byte sendok;
unsigned long minut1 = 0; //счётчик 1 минут
float Pi, To, Ho, Bo, Ti, Hi; //данные погоды
int bright; int dt;
//=======================================================================================================
void setup() {
Serial.begin(9600);
disp.set(1);//0 - 7;
disp.init(D4056A);//D4056A is the type of the module
disp.clearDisplay();
for (byte i=0; i<17; i++) {
disp.display(3,i); delay (100);
}
Serial.print (".");
si7021.initialize();
bmp.begin();
radio.begin();
//radio.setAutoAck(1);
radio.setRetries(15,15);
//radio.setChannel(42); // Указываем канал передачи данных (от 0 до 127), 5 - значит передача данных осуществляется на частоте 2,405 ГГц (на одном канале может быть только 1 приёмник и до 6 передатчиков)
radio.setDataRate(RF24_250KBPS); // скорость обмена данными RF24_250KBPS, RF24_1MBPS или RF24_2MBPS
radio.setPALevel (RF24_PA_MAX); // Указываем мощность передатчика (RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_HIGH=-6dBm, RF24_PA_MAX=0dBm)
delayMicroseconds(225);
radio.openWritingPipe(pipe); // открыть канал на отправку
radio.openReadingPipe(1,pipe); // открыть канал на приём
radio.startListening(); // приём
radio.printDetails();
delayMicroseconds(225);
Serial.print (".");
}
//=======================================================================================================
void loop() {
if (radio.available()) { radio.read(&datadat, sizeof(datadat)); //если что-то пришло по nRF
if (datadat[0]==79) { datadat[0]=73; //если пришёл сигнал с внешнего датчика
To=datadat[3];To=To/10; Ho=datadat[4];Ho=Ho/10;Bo=datadat[2];Bo=Bo/100;
Serial.print("To.txt="); Serial.print(To,1); Serial.print("Ho.txt="); Serial.print(Ho,1); Serial.print("Bo.txt="); Serial.println(Bo,1);
dt=round(To);dt=dt*10;disp.clearDisplay(); disp.display(dt); disp.display(3,17);
}
}
if (millis()/10000 == minut1) { minut1=(millis()/10000)+1; //раз в минуту
bright=map(analogRead(A3), 50, 900, 0, 7); disp.set(bright); Serial.print(" Bright="); Serial.print(bright); //яркость дисплея
temp=(bmp.readPressure()/133.33); datadat[7]=temp*10; //давление *10
si7021.getHumidity(temp); datadat[6]=temp*10; //влажность *10
si7021.getTemperature(temp); datadat[5]=temp*10; //температура *10
si7021.triggerMeasurement();
Serial.print(" Ti.txt="); Serial.print((datadat[5]/10)); Serial.print(" Hi.txt="); Serial.print(datadat[6]/10); Serial.print(" P.txt="); Serial.println(datadat[7]/10);
radio.stopListening(); delayMicroseconds(225);
if (radio.write(&datadat, sizeof(datadat))) { Serial.print("send"); disp.display(3,17); datadat[2]=0;} else disp.display(3,12);
delayMicroseconds(225); radio.startListening(); delayMicroseconds(225);
}
}
//-------------------------------------------------------------------------------------------------------
По составу, думаю понятно из кода (корявого, но я не программер). si7021 - датчик температуры и влажности, BMP085 - давление, ну и ардуина+nrf24L01
Это уже в прошивке базы. Она собрана на ESP8266, отправляет по wifi, там очень много лишнего, не вижу смысла выкладывать, сама подпрограмма отправки - вот:
bool Narodmon() { //отправка на narodmon
buf="#"+Hostname+"\r\n#in1#"+in1+"\r\n#in2#"+in2+"\r\n#on1#"+on1+"\r\n#on2#"+on2;
if (sndnmi) buf=buf+"\r\n#P#"+Pi+"\r\n#IT#"+Ti+"\r\n#IH#"+Hi; //показания домашнего получены-на отправку.
if (sndnmo) buf=buf+"\r\n#OT#"+To+"\r\n#OH#"+Ho+"\r\n#OB#"+Bo; //показания уличного получены-на отправку.
WiFiClient client;
if (!client.connect("narodmon.ru", 8283)) {Serial.print("Dt.txt=\"\rError Send\""); sendToNextion(); client.stop(); return false; }
else {client.print(buf); client.print(F("##"));
line = client.readStringUntil('\r');
sendToNextion();Serial.print("Dt.txt=\""); Serial.print(line); Serial.print("\""); sendToNextion();
ersend=0;sndnmi=0;sndnmo=0; //обнуляем счётчик ошибки и флаги отправки
}
client.stop(); return true;
}
В line считывается тут данные переданные от народмон, для управления релюшками дома, ну а если ответных команд нет, то в line просто приходит "OK" (которое обычно как раз отображается на страничке этой esp'шки). ЗЫ Аккум сел, так что ничего с внешнего датчика нет, а поправить я смогу, только вернувшить с командировки, а это под НГ, ну заодно ионистор подъедет вместо умерших аккумов). Время работы там - это время с последнего отключения света, у меня его часто отключают, никак не приспособлю аккум, да и пока электромеханический замок не поставил на дверь, вроде как аккум и не нужен.
Это уже в прошивке базы. Она собрана на ESP8266, отправляет по wifi, там очень много лишнего, не вижу смысла выкладывать, сама подпрограмма отправки - вот:
bool Narodmon() { //отправка на narodmon
buf="#"+Hostname+"\r\n#in1#"+in1+"\r\n#in2#"+in2+"\r\n#on1#"+on1+"\r\n#on2#"+on2;
if (sndnmi) buf=buf+"\r\n#P#"+Pi+"\r\n#IT#"+Ti+"\r\n#IH#"+Hi; //показания домашнего получены-на отправку.
if (sndnmo) buf=buf+"\r\n#OT#"+To+"\r\n#OH#"+Ho+"\r\n#OB#"+Bo; //показания уличного получены-на отправку.
WiFiClient client;
if (!client.connect("narodmon.ru", 8283)) {Serial.print("Dt.txt=\"\rError Send\""); sendToNextion(); client.stop(); return false; }
else {client.print(buf); client.print(F("##"));
line = client.readStringUntil('\r');
sendToNextion();Serial.print("Dt.txt=\""); Serial.print(line); Serial.print("\""); sendToNextion();
ersend=0;sndnmi=0;sndnmo=0; //обнуляем счётчик ошибки и флаги отправки
}
client.stop(); return true;
}
В line считывается тут данные переданные от народмон, для управления релюшками дома, ну а если ответных команд нет, то в line просто приходит "OK" (которое обычно как раз отображается на страничке этой esp'шки). ЗЫ Аккум сел, так что ничего с внешнего датчика нет, а поправить я смогу, только вернувшить с командировки, а это под НГ, ну заодно ионистор подъедет вместо умерших аккумов). Время работы там - это время с последнего отключения света, у меня его часто отключают, никак не приспособлю аккум, да и пока электромеханический замок не поставил на дверь, вроде как аккум и не нужен.
Скажите прошестил данную тему. У меня датчик орегон. решил из всех кодов воспользоваться вашей библой. но он ругается на функцию oregon.capture. Пример: 'oregon' was not declared in this scope. Типа не задекларирована она. Странно. код глянул вроде все норм. Не скажите в чем может быть беда. И еще никто не пробывал снимать данные с датчиков фирмы Diggo?
Просто все 400+ постов я осилил))) и нигде не увидел людей которые бы тестили манчестерский декод с другими метеодатчиками. Предлагаю совместо изучить вопрос с этим датчиком ибо как я увидел он относительно дешев) А это думаю большой плюс. Как все подключу проверю отпишу сюда. + у меня лежит еще один датчик от какой то метеостанции но не орегон тоже.
А и еще вопрос. Не нашел тут ничего по данной теме особо толкового. Можете подсказать как "лучше" организовать работу 4-5 датчиков? я имею ввиду определение какой датчик какой. Если по каналу то их всего 3и у большинства датчиков как я понял. Если по ИД то оно вроде меняется при перезапуске датчика. Вот сижу на работе и думаю куда копнуть пока теорию как говориться. Заранее спасибо за ответы
Не очень понятно, какой у этого китайского датчика тип гигрометра. Если такое же фуфло, как у Орегона, то при трёх каналах копать наверное и не стоит...
Ну там в орегоне кто помнить какие отклонения по гигроментру) Мне в любом счлучии нужны какие то 4 датчика для чтения температуры в 4х помещениях. вопрос как их определять с какого какие показания. либо по ИД самый верный вариант но это до первого зависания либо до конца батареек что не очень удобно ибо надо будет прописывать ид каждый раз в скетче((( блин я в замешательств
int Vbg() {
ADMUX = (1<<REFS0)|(0<<REFS1)|(1<<MUX3)|(1<<MUX2)|(1<<MUX1)|(0<<MUX0);
long buffersamp=0;
for (int n=0x0; n<=0xff; n++ ) {
ADCSRA = 0xc7;
while (bit_is_set(ADCSRA,ADSC));
buffersamp += ADC; }
buffersamp >>=4; //16368 full scale 14bit
ADCSRA &= ~(1 << ADEN); // отключаем АЦП
return buffersamp;
}
может вместо того чтоб копипастить в свои проекты непонятные для вас опереции с регистрами микроконтроллера, вы воспользуетесь высокоуровневой библиотекой sleep.h из пакета avr-libc, которая входит в состав Arduino?
В общем так. Ниче не пашет((( с датчиком Digoo. И вообще не могу с нег очто либо принять глухо в эфире( Подскажите как я могу определить он вообще посылает что либо или нет. Приемник работает 100 процентов на 433.92 и датчик тоже. Но даже библа RS не видит ничего по прерываниям. Не могу понять почему и куда начать копать. Естьб ли еще какие то библиотеки для чтения эфира в целом?
Крч спомощью прерываний напрямую. я увидел что датчик все же передает что то)) Но теперь не ясно как отсортировать данные данные по прерываниям от общего мусора. Может кто подкинет скетч код какой нить. который можно попробывать? Использовал простой код такого типа чтобы определить работает ли датчик вообще:
volatile int length = 0;
volatile int start_time = 0;
void setup() {
Serial.begin(115200);
// Привязываем к Pin2 прерывание по фронту сигнала
attachInterrupt(0, rising, RISING);
}
void loop() { }
//Обработчик прерывания на возрастание сигнала
void rising() {
// Привязываем к Pin2 прерывание по срезу сигнала
attachInterrupt(0, falling, FALLING);
//сохраняем значение времени начала импульса
start_time = micros();
}
//Обработчик прерывания по срезу сигнала
void falling() {
// Привязываем к Pin2 прерывание по фронту сигнала
attachInterrupt(0, rising, RISING);
//сохраняем значение длительности импульса
length = micros() - start_time;
Serial.println(length);
}
enjoyneering - Вы сначала на код посмотрите, а потом предлагайте использовать sleep а не копипастить непонятные регистры. ) Это вообще-то напряжения питания контроллера определяется.
ИМХО для чтения эфира в целом нужен осциллограф или его подобие. Иначе АРУ приёмника не даст вам понять, где шум, а где пакет... А потом уже смотреть, что за пакет: метод кодирования, скорость передачи данных и т.д. Это вообще-то достаточно большая работа - раскопать весь пакет...
ДА я уже нагуглил тут это) Осцила нет и анализатора нет(( крч гиблое дело в моих руках. Сегодня принесут датчик орегон заодно проверю вашу библиотеку. Если что напишу
Крч за последние 20 мин не разу не вывел результат((( Я так понимаю в вашей бибиле же идут проверки пакетов и я так понял что не проходят проверки и кореляции как бы и поэтмоу не выводит так?
В том и дело я тоже ваш код иучил в cpp странно должно выводить но условие не выполняется по выводу значений. а вот исходный код под ООК работает. Если не разберусь могу остановиться на нем, но с ним не удобно он громоздкий. Да и опыта большого в библиотек перестраивать код у меня нет( У вас там стоит 20. Почему 20? и насколько можно попробывать поставить?
LENGTH_TOLERANCE - Допустимое отклонение мкс при поиске в эфире последоветельностей из трёх импульсов преамбулы. Если частота передачи данных датчика чуток отличается, то варьирование этого параметр поможет поймать пакет за хвост.
Крч все без результата((( Скажите госопда. А как можно использовать две функции одновременно по одному и тому же прерыванию со 2го пина? Т.е. мне надо чтобы моя дуня и слушала эфир на наличие данных от датчика и в тоже время слушала эфир спомощью библиотеки RS Switch от радио датчиков обычных дым, дверь и т.д. Пробывал в параллель вроде не пашет
В общем все я вопросы порешал кроме как с библой поросенка чет не хочет((( Игрался я по всякому с LENGTH_TOLERANCE. датчик перезагружал. И нифига( Свой вопрос по поводу одновременной работы двых библиотек решил так. Просто вторую подключил на прерыванию (1) и все заработало. Если есть идеи по поводу библиотеки поросенка, буду рад услышать. Спасибо
Ребят вопрос. Как можно в параллель данного кода в дуню закинуть отправку данных по nRF??? у меня когда я вставляю в loop или в функцию reportSerial. Виснет как я понял дуня и каждый раз заново выполняет void setup. Код который ниже у меня работает, но есть необходимост ьпринятые данные пересылать серверу по nRF. Сделано так по причине того что на сервере нет места под этот кусок кода) Память под завязку да и прерывания пины используются.
// Oregon V2 decoder added - Dominique Pierre
// Oregon V3 decoder revisited - Dominique Pierre
// New code to decode OOK signals from weather sensors, etc.
// 2010-04-11 <jcw@equi4.com> <a data-cke-saved-href="<a href="http://opensource.org/licenses/mit-license.php" rel="nofollow">http://opensource.org/licenses/mit-license.php</a>" href="<a href="http://opensource.org/licenses/mit-license.php" rel="nofollow">http://opensource.org/licenses/mit-license.php</a>" rel="nofollow"><a href="http://opensource.org/licenses/mit-license.php" rel="nofollow">http://opensource.org/licenses/mit-license.php</a></a>
// $Id: ookDecoder.pde 5331 2010-04-17 10:45:17Z jcw $
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 (32 <= 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 {
return -1;
}
return total_bits == 160 ? 1: 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;
}
};
class CrestaDecoder : public DecodeOOK {
public:
CrestaDecoder () {}
virtual char decode (word width) {
if (200 <= width && width < 1300) {
byte w = width >= 750;
switch (state) {
case UNKNOWN:
if (w == 1)
++flip;
else if (2 <= flip && flip <= 10)
state = T0;
else
return -1;
break;
case OK:
if (w == 0)
state = T0;
else
gotBit(1);
break;
case T0:
if (w == 0)
gotBit(0);
else
return -1;
break;
}
} else if (width >= 2500 && pos >= 7)
return 1;
else
return -1;
return 0;
}
};
class KakuDecoder : public DecodeOOK {
public:
KakuDecoder () {}
virtual char decode (word width) {
if (180 <= width && width < 450 || 950 <= width && width < 1250) {
byte w = width >= 700;
switch (state) {
case UNKNOWN:
case OK:
if (w == 0)
state = T0;
else
return -1;
break;
case T0:
if (w)
state = T1;
else
return -1;
break;
case T1:
state += w + 1;
break;
case T2:
if (w)
gotBit(0);
else
return -1;
break;
case T3:
if (w == 0)
gotBit(1);
else
return -1;
break;
}
} else if (width >= 2500 && 8 * pos + bits == 12) {
for (byte i = 0; i < 4; ++i)
gotBit(0);
alignTail(2);
return 1;
} else
return -1;
return 0;
}
};
class XrfDecoder : public DecodeOOK {
public:
XrfDecoder () {}
// see also <a data-cke-saved-href="<a href="http://davehouston.net/rf.htm" rel="nofollow">http://davehouston.net/rf.htm</a>" href="<a href="http://davehouston.net/rf.htm" rel="nofollow">http://davehouston.net/rf.htm</a>" rel="nofollow"><a href="http://davehouston.net/rf.htm" rel="nofollow">http://davehouston.net/rf.htm</a></a>
virtual char decode (word width) {
if (width > 2000 && pos >= 4)
return 1;
if (width > 5000)
return -1;
if (width > 4000 && state == UNKNOWN)
state = OK;
else if (350 <= width && width < 1800) {
byte w = width >= 720;
switch (state) {
case OK:
if (w == 0)
state = T0;
else
return -1;
break;
case T0:
gotBit(w);
break;
}
} else
return -1;
return 0;
}
};
class HezDecoder : public DecodeOOK {
public:
HezDecoder () {}
// see also <a data-cke-saved-href="<a href="http://homeeasyhacking.wikia.com/wiki/Home_Easy_Hacking_Wiki" rel="nofollow">http://homeeasyhacking.wikia.com/wiki/Home_Easy_Hacking_Wiki</a>" href="<a href="http://homeeasyhacking.wikia.com/wiki/Home_Easy_Hacking_Wiki" rel="nofollow">http://homeeasyhacking.wikia.com/wiki/Home_Easy_Hacking_Wiki</a>" rel="nofollow"><a href="http://homeeasyhacking.wikia.com/wiki/Home_Easy_Hacking_Wiki" rel="nofollow">http://homeeasyhacking.wikia.com/wiki/Home_Easy_Hacking_Wiki</a></a>
virtual char decode (word width) {
if (200 <= width && width < 1200) {
byte w = width >= 600;
gotBit(w);
} else if (width >= 5000 && pos >= 5 /*&& 8 * pos + bits == 50*/) {
for (byte i = 0; i < 6; ++i)
gotBit(0);
alignTail(7); // keep last 56 bits
return 1;
} else
return -1;
return 0;
}
};
// 868 MHz decoders
class VisonicDecoder : public DecodeOOK {
public:
VisonicDecoder () {}
virtual char decode (word width) {
if (200 <= width && width < 1000) {
byte w = width >= 600;
switch (state) {
case UNKNOWN:
case OK:
state = w == 0 ? T0 : T1;
break;
case T0:
gotBit(!w);
if (w)
return 0;
break;
case T1:
gotBit(!w);
if (!w)
return 0;
break;
}
// sync error, flip all the preceding bits to resync
for (byte i = 0; i <= pos; ++i)
data[i] ^= 0xFF;
} else if (width >= 2500 && 8 * pos + bits >= 36 && state == OK) {
for (byte i = 0; i < 4; ++i)
gotBit(0);
alignTail(5); // keep last 40 bits
// only report valid packets
byte b = data[0] ^ data[1] ^ data[2] ^ data[3] ^ data[4];
if ((b & 0xF) == (b >> 4))
return 1;
} else
return -1;
return 0;
}
};
class EMxDecoder : public DecodeOOK {
public:
EMxDecoder () {}
// see also <a data-cke-saved-href="<a href="http://fhz4linux.info/tiki-index.php?page=EM+Protocol" rel="nofollow">http://fhz4linux.info/tiki-index.php?page=EM+Protocol</a>" href="<a href="http://fhz4linux.info/tiki-index.php?page=EM+Protocol" rel="nofollow">http://fhz4linux.info/tiki-index.php?page=EM+Protocol</a>" rel="nofollow"><a href="http://fhz4linux.info/tiki-index.php?page=EM+Protocol" rel="nofollow">http://fhz4linux.info/tiki-index.php?page=EM+Protocol</a></a>
virtual char decode (word width) {
if (200 <= width && width < 1000) {
byte w = width >= 600;
switch (state) {
case UNKNOWN:
if (w == 0)
++flip;
else if (flip > 20)
state = OK;
else
return -1;
break;
case OK:
if (w == 0)
state = T0;
else
return -1;
break;
case T0:
gotBit(w);
break;
}
} else if (width >= 1500 && pos >= 9)
return 1;
else
return -1;
return 0;
}
};
class KSxDecoder : public DecodeOOK {
public:
KSxDecoder () {}
// see also <a data-cke-saved-href="<a href="http://www.dc3yc.homepage.t-online.de/protocol.htm" rel="nofollow">http://www.dc3yc.homepage.t-online.de/protocol.htm</a>" href="<a href="http://www.dc3yc.homepage.t-online.de/protocol.htm" rel="nofollow">http://www.dc3yc.homepage.t-online.de/protocol.htm</a>" rel="nofollow"><a href="http://www.dc3yc.homepage.t-online.de/protocol.htm" rel="nofollow">http://www.dc3yc.homepage.t-online.de/protocol.htm</a></a>
virtual char decode (word width) {
if (200 <= width && width < 1000) {
byte w = width >= 600;
switch (state) {
case UNKNOWN:
gotBit(w);
bits = pos = 0;
if (data[0] != 0x95)
state = UNKNOWN;
break;
case OK:
state = w == 0 ? T0 : T1;
break;
case T0:
gotBit(1);
if (!w)
return -1;
break;
case T1:
gotBit(0);
if (w)
return -1;
break;
}
} else if (width >= 1500 && pos >= 6)
return 1;
else
return -1;
return 0;
}
};
class FSxDecoder : public DecodeOOK {
public:
FSxDecoder () {}
// see also <a data-cke-saved-href="<a href="http://fhz4linux.info/tiki-index.php?page=FS20%20Protocol" rel="nofollow">http://fhz4linux.info/tiki-index.php?page=FS20%20Protocol</a>" href="<a href="http://fhz4linux.info/tiki-index.php?page=FS20%20Protocol" rel="nofollow">http://fhz4linux.info/tiki-index.php?page=FS20%20Protocol</a>" rel="nofollow"><a href="http://fhz4linux.info/tiki-index.php?page=FS20%20Protocol" rel="nofollow">http://fhz4linux.info/tiki-index.php?page=FS20%20Protocol</a></a>
virtual char decode (word width) {
if (300 <= width && width < 775) {
byte w = width >= 500;
switch (state) {
case UNKNOWN:
if (w == 0)
++flip;
else if (flip > 20)
state = T1;
else
return -1;
break;
case OK:
state = w == 0 ? T0 : T1;
break;
case T0:
gotBit(0);
if (w)
return -1;
break;
case T1:
gotBit(1);
if (!w)
return -1;
break;
}
} else if (width >= 1500 && pos >= 5)
return 1;
else
return -1;
return 0;
}
};
OregonDecoderV2 orscV2;
OregonDecoderV3 orscV3;
CrestaDecoder cres;
KakuDecoder kaku;
XrfDecoder xrf;
HezDecoder hez;
VisonicDecoder viso;
EMxDecoder emx;
KSxDecoder ksx;
FSxDecoder fsx;
#define PORT 2
volatile word pulse;
#if defined(__AVR_ATmega1280__)
void ext_int_1(void) {
#else
ISR(ANALOG_COMP_vect) {
#endif
static word last;
// determine the pulse length in microseconds, for either polarity
pulse = micros() - last;
last += pulse;
}
void reportSerial (const char* s, class DecodeOOK& decoder) {
byte pos;
const byte* data = decoder.getData(pos);
Serial.print(s);
Serial.print(' ');
for (byte i = 0; i < pos; ++i) {
Serial.print(data[i] >> 4, HEX);
Serial.print(data[i] & 0x0F, HEX);
}
// Serial.print(' ');
// Serial.print(millis() / 1000);
Serial.println();
decoder.resetDecoder();
}
void setup () {
Serial.begin(115200);
Serial.println("\n[ookDecoder]");
#if !defined(__AVR_ATmega1280__)
pinMode(13 + PORT, INPUT); // use the AIO pin
digitalWrite(13 + PORT, 1); // enable pull-up
// use analog comparator to switch at 1.1V bandgap transition
ACSR = _BV(ACBG) | _BV(ACI) | _BV(ACIE);
// set ADC mux to the proper port
ADCSRA &= ~ bit(ADEN);
ADCSRB |= bit(ACME);
ADMUX = PORT - 1;
#else
attachInterrupt(1, ext_int_1, CHANGE);
DDRE &= ~_BV(PE5);
PORTE &= ~_BV(PE5);
#endif
}
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);
if (cres.nextPulse(p))
reportSerial("CRES", cres);
if (kaku.nextPulse(p))
reportSerial("KAKU", kaku);
if (xrf.nextPulse(p))
reportSerial("XRF", xrf);
if (hez.nextPulse(p))
reportSerial("HEZ", hez);
}
if (p != 0) {
if (viso.nextPulse(p))
reportSerial("VISO", viso);
if (emx.nextPulse(p))
reportSerial("EMX", emx);
if (ksx.nextPulse(p))
reportSerial("KSX", ksx);
if (fsx.nextPulse(p))
reportSerial("FSX", fsx);
}
}
Крч. У меня вроде то норм отправляет то перезапуск идет как бы то виснет. но все это связанно с nRF думаю дело в питании . Как соберу в норм пайке все потестирую еще. Жду платы с китая просто. Отпишу позже
Вопрос по основному коду который вначале темы. Кто может подсказать почему может происходить зависание функции reportSerial? Т.е. допустим. принял данные с одного датчика и потмо тишина не принимает больше? Цель какая. Я придумал как можно использовать неограниченное количество датчиков (теоритически). Суть такая: А скетче я создал массив для хранения ИД номеров датчиков. И функцию которая заполняет этот массив если он пустой теми ИД которые приходят и потом оперирует данными. Сут ьтакая мне надо получать данные от датчиков сигнализации + от датчиков Oregon и потом по радиоканалу но на частоте 2.4 с помощью nRF отправлять на другой блок управления. ВОт код
#include <RCSwitch.h>
#include <Wire.h>
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RCSwitch mySwitch = RCSwitch();
const uint64_t pipe = 0xF0F1F2F3F4LL;
RF24 radio(9, 10); // CE, CSN
int PORT=2;
int Def1=A5;
int Def2=A6;
int Def3=A7;
int Led1=6;
int Led2=7;
int Led3=8;
int Protocol[4];
int ID[3];
int value;
int RCCod;
int Temp;
int Hum;
int Bat;
int S;
unsigned long upd[8];
class DecodeOOK {
protected:
byte total_bits, bits, flip, state, pos, data[12];
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;}
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;}
void manchester (char value) {
flip ^= value; // manchester code, long pulse flips the bit
gotBit(flip);}
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;}
};
class OregonDecoderV2 : public DecodeOOK {
public:
OregonDecoderV2() {}
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 (100 <= width && width < 1200)
{
byte w = width >= 700;
switch (state)
{
case UNKNOWN:
if (w != 0)
{
// Long pulse
++flip;
}
else if (w == 0 && 5 <= 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 >= 1500 && pos >= 8)
{
return 1;
}
else
{
return -1;
}
return 0;
}
};
OregonDecoderV2 orscV2;
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]>>4)
{
case 0x1:
channel = 1;
break;
case 0x2:
channel = 2;
break;
case 0x3:
channel = 3;
break;
case 0x4:
if((data[2]&0xF)==3){
channel = 4;
} else {
channel = 3;
}
break;
case 0x5:
channel = 5;
break;
case 0x6:
channel = 6;
break;
case 0x7:
channel = 7;
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;
}
void reportSerial (const char* s, class DecodeOOK& decoder) {
byte pos;
const byte* data = decoder.getData(pos);
if( pos>8 ){
if( data[8] == (Sum(8,data)-0xa)&0xFF ){
unsigned long m = millis();
upd[channel(data)]=m;
// Serial.print(" "+String(channel(data))+" "+String(serial(data)));
// Serial.print(" "+String(temperature(data),1)+" "+String(humidity(data))+"%");
// if(battery(data) == 0xC){Serial.println(" LOW");} else {Serial.println(" OK");}
S=int(serial(data));
Temp=temperature(data)*10;
Hum=humidity(data);
if(battery(data) == 0xC){Bat=100;} else {Bat=0;}
}
}
if (ID[0]==serial(data) || ID[1]==serial(data) || ID[2]==serial(data) || ID[3]==serial(data)){
if (ID[0]==serial(data)){
Protocol[0]=100;
Protocol[1]=201;
Protocol[2]=Temp;
Protocol[3]=Hum;
Protocol[4]=Bat;
radio.write(&Protocol, sizeof(Protocol));}
if (ID[1]==serial(data)){
Protocol[0]=100;
Protocol[1]=201;
Protocol[2]=Temp;
Protocol[3]=Hum;
Protocol[4]=Bat;
radio.write(&Protocol, sizeof(Protocol));}
if (ID[2]==serial(data)){
Protocol[0]=100;
Protocol[1]=201;
Protocol[2]=Temp;
Protocol[3]=Hum;
Protocol[4]=Bat;
radio.write(&Protocol, sizeof(Protocol));}
if (ID[3]==serial(data)){
Protocol[0]=100;
Protocol[1]=201;
Protocol[2]=Temp;
Protocol[3]=Hum;
Protocol[4]=Bat;
radio.write(&Protocol, sizeof(Protocol));}}
else if(ID[0]==0){ID[0]=int(serial(data));}
else if(ID[1]==0){ID[1]=int(serial(data));}
else if(ID[2]==0){ID[2]=int(serial(data));}
else if(ID[3]==0){ID[3]=int(serial(data));}
Serial.println("ID0 "+ID[0]);
Serial.println("ID1 "+ID[1]);
Serial.println("ID2 "+ID[2]);
Serial.println("ID3 "+ID[3]);
decoder.resetDecoder();
}
void setup () {
Serial.begin(9600);
radio.begin();
delay(200);
radio.setChannel(100); // канал (0-127)
radio.setDataRate(RF24_1MBPS);
radio.setPALevel(RF24_PA_LOW);
radio.openWritingPipe(pipe); // открываем трубу на передачу.
ID[0]=0;
ID[1]=0;
ID[2]=0;
ID[3]=0;
Serial.println("Init...");
pinMode(PORT, INPUT);
pinMode(3, INPUT);
pinMode(Def1, OUTPUT);
pinMode(Def2, OUTPUT);
pinMode(Def3, OUTPUT);
pinMode(Led1, OUTPUT);
pinMode(Led2, OUTPUT);
pinMode(Led3, OUTPUT);
attachInterrupt(digitalPinToInterrupt(PORT), ext_int_1, CHANGE);
mySwitch.enableReceive(1);
//digitalWrite(Led1,HIGH);
}
void loop () {
cli();
word p = pulse;
pulse = 0;
sei();
if (p != 0) {
if (orscV2.nextPulse(p))
reportSerial("OSV2", orscV2);}
if (mySwitch.available()) {
RCCod = mySwitch.getReceivedValue();
if (RCCod==24498){
RCCod=0;
Serial.println("Def1");
analogWrite(Def1,255);}
if (RCCod==12270){
RCCod=0;
Serial.println("Def2");
analogWrite(Def2,255);}
if (RCCod==6489){
RCCod=0;
Serial.println("Def3");
analogWrite(Def3,255);}}
else
{analogWrite(Def1,0); analogWrite(Def2,0); analogWrite(Def3,0);}
}
Скажите а в ваших библиотеках нет в коде какой либо перезагрузки предусмотренной? Ну типа если что то там происходит то надо ребутнуть дуню? У меня ваши библиотеки заработали стабильно. Нахимичил) Новсе равно передача по nRF данных вешает Arduino не ясно почему. даже без модуля nRF все виснит и перезагружается
Еще для информации, прошивка под esp8266 принимающая датчики ORegon, у себя залил на WemosD1 mini . работает. http://serg22.ru/radio/esp8266/
Вот бы код посмотреть. Я так и не смог решить проблему с пропусками сигналов от приемника. У меня получилось, что обработка прерываний по ноге от приемника совершенно не гарантируется при работе WiFi...
с другой стороны, если не нужна 100% точность приема, то и нормально. я правда думаю себе заказать приемники на Telecontrolli https://www.electronshik.ru/item/rrq3-433-163578 супергетеродинные, длжно получше быть и антена штырь есть
Вот бы код посмотреть. Я так и не смог решить проблему с пропусками сигналов от приемника. У меня получилось, что обработка прерываний по ноге от приемника совершенно не гарантируется при работе WiFi...
А зачем нужен гарантированный прием от погодных датчиков?
Ведь для слежения за погодой не нужны мгновенные данные.
Я использую библиотек blynk и от поросенка для чтения датчиков. Плюс к самой есп подключен датчик BMP280 и геркон для подсчета оборотов хомячкового колеса.
Все более/менее на макете работает, правда пришлось разные временные задержки устанавливать для передачи данных блинком в сеть разными пакетами иначе при передачи данных одним пакетом отваливался контролер от сети постоянно. Еще при передачи пакетов пришлось отключать прерывание приемника. Т.е. периодически приеменик отключается, при этом нет сильно больших промежутков между приемами данных (не больше 10 мин.)
зы.
Хомяк, попался спортивный. Иногда за сутки 7 км пробегает.
Согласен, паять, мудрить с корпусом. В моём 3АА тоже хватит на год не меньше (10мА 0.5 секунды каждые 300 сек - просто чаще на народмон бессмысленно отправлять). Но суть в том, что я разочаровался в орегоне, в первую очередь из-за датчика влажности, а изначально я считал его примером, пока он у меня не появился. В самодельном можно использоать куда более интересные датчики, при этом используя минимум кода с обеих сторон, что позволяет мне запихнуть в одну мини.про кучу всего, а тут влезал только декодер и с трудом что-то ещё по мелочи совсем. Опять же расширяемость, сейчас у меня передаётся номер датчика, напряжение аккума, влажность и температура, можно же насобирать гораздо больше, из-за высокой частоты передачи можно использовать более мелкий корпус, и гораздо большее количество данных за единицу времени, с CRC и контролем получения посылки. Да и приёмник же Вы паятете всё равно, почему бы заодно не смаять передатчик? Тем более никаких подводных камней - датчик (4 провода), передатчик (6 проводов), батарейка (2 провода) ну и с платы отломать диоды и стабилизатор, чтоб не жрали, всё. И заодно никаких помех и соседей )
Ничего не имею против проекта, он интересен, и работает теперь у моей мамы ) Для меня данный код слишком сложен, поэтому суть в каких-то доработках приближался к нулю.
Где можно скетч посмотреть и состав оборудования?
Передатчик
С приёмником сложнее, т.к. 1ый приёмник у меня часы с фотки, они ловят показания, отображают на индикаторе и добавив свои измерения отправляют в прихожку на базу, но думаю будет понятно, всё подписано.
По составу, думаю понятно из кода (корявого, но я не программер). si7021 - датчик температуры и влажности, BMP085 - давление, ну и ардуина+nrf24L01
А на narodmon каким образом попадают данные?
Это уже в прошивке базы. Она собрана на ESP8266, отправляет по wifi, там очень много лишнего, не вижу смысла выкладывать, сама подпрограмма отправки - вот:
В line считывается тут данные переданные от народмон, для управления релюшками дома, ну а если ответных команд нет, то в line просто приходит "OK" (которое обычно как раз отображается на страничке этой esp'шки). ЗЫ Аккум сел, так что ничего с внешнего датчика нет, а поправить я смогу, только вернувшить с командировки, а это под НГ, ну заодно ионистор подъедет вместо умерших аккумов). Время работы там - это время с последнего отключения света, у меня его часто отключают, никак не приспособлю аккум, да и пока электромеханический замок не поставил на дверь, вроде как аккум и не нужен.
Это уже в прошивке базы. Она собрана на ESP8266, отправляет по wifi, там очень много лишнего, не вижу смысла выкладывать, сама подпрограмма отправки - вот:
В line считывается тут данные переданные от народмон, для управления релюшками дома, ну а если ответных команд нет, то в line просто приходит "OK" (которое обычно как раз отображается на страничке этой esp'шки). ЗЫ Аккум сел, так что ничего с внешнего датчика нет, а поправить я смогу, только вернувшить с командировки, а это под НГ, ну заодно ионистор подъедет вместо умерших аккумов). Время работы там - это время с последнего отключения света, у меня его часто отключают, никак не приспособлю аккум, да и пока электромеханический замок не поставил на дверь, вроде как аккум и не нужен.
Ясно. Спасибо за ответ.
udavst никак у меня не получилось выяснить причину. Дабы не засорять ветку, можно с Вами пообщаться лично? Вот мой эл.адрес stealth85@list.ru
Скажите прошестил данную тему. У меня датчик орегон. решил из всех кодов воспользоваться вашей библой. но он ругается на функцию oregon.capture. Пример: 'oregon' was not declared in this scope. Типа не задекларирована она. Странно. код глянул вроде все норм. Не скажите в чем может быть беда. И еще никто не пробывал снимать данные с датчиков фирмы Diggo?
Судя по всему, где-то не объявили библиотеку. Вы пример из поста 364 запускали? Он вроде должен работать...
С новой библой второй и примером вроде норм. Попробую отпишу. Про Diggo не знает никто? Вот такой лежит у меня пока не пробывал https://ru.aliexpress.com/item/Digoo-Hygrometer-Thermometer-DG-R8H-433MHz-Wireless-Digital-Weather-Station-Outdoor-Sensor-for-TH11300-TH8380-TH1981/32826519857.html?spm=a2g0s.9042311.0.0.VnOk0U
нет библиотека откомпилилась нормально из 437 поста
Просто все 400+ постов я осилил))) и нигде не увидел людей которые бы тестили манчестерский декод с другими метеодатчиками. Предлагаю совместо изучить вопрос с этим датчиком ибо как я увидел он относительно дешев) А это думаю большой плюс. Как все подключу проверю отпишу сюда. + у меня лежит еще один датчик от какой то метеостанции но не орегон тоже.
А и еще вопрос. Не нашел тут ничего по данной теме особо толкового. Можете подсказать как "лучше" организовать работу 4-5 датчиков? я имею ввиду определение какой датчик какой. Если по каналу то их всего 3и у большинства датчиков как я понял. Если по ИД то оно вроде меняется при перезапуске датчика. Вот сижу на работе и думаю куда копнуть пока теорию как говориться. Заранее спасибо за ответы
Не очень понятно, какой у этого китайского датчика тип гигрометра. Если такое же фуфло, как у Орегона, то при трёх каналах копать наверное и не стоит...
Ну там в орегоне кто помнить какие отклонения по гигроментру) Мне в любом счлучии нужны какие то 4 датчика для чтения температуры в 4х помещениях. вопрос как их определять с какого какие показания. либо по ИД самый верный вариант но это до первого зависания либо до конца батареек что не очень удобно ибо надо будет прописывать ид каждый раз в скетче((( блин я в замешательств
может вместо того чтоб копипастить в свои проекты непонятные для вас опереции с регистрами микроконтроллера, вы воспользуетесь высокоуровневой библиотекой sleep.h из пакета avr-libc, которая входит в состав Arduino?
пример как надо с подробным описанием здесь
Вы не ошиблись постом?))) Или это не мне?
В общем так. Ниче не пашет((( с датчиком Digoo. И вообще не могу с нег очто либо принять глухо в эфире( Подскажите как я могу определить он вообще посылает что либо или нет. Приемник работает 100 процентов на 433.92 и датчик тоже. Но даже библа RS не видит ничего по прерываниям. Не могу понять почему и куда начать копать. Естьб ли еще какие то библиотеки для чтения эфира в целом?
Крч спомощью прерываний напрямую. я увидел что датчик все же передает что то)) Но теперь не ясно как отсортировать данные данные по прерываниям от общего мусора. Может кто подкинет скетч код какой нить. который можно попробывать? Использовал простой код такого типа чтобы определить работает ли датчик вообще:
enjoyneering - Вы сначала на код посмотрите, а потом предлагайте использовать sleep а не копипастить непонятные регистры. ) Это вообще-то напряжения питания контроллера определяется.
ИМХО для чтения эфира в целом нужен осциллограф или его подобие. Иначе АРУ приёмника не даст вам понять, где шум, а где пакет... А потом уже смотреть, что за пакет: метод кодирования, скорость передачи данных и т.д. Это вообще-то достаточно большая работа - раскопать весь пакет...
ДА я уже нагуглил тут это) Осцила нет и анализатора нет(( крч гиблое дело в моих руках. Сегодня принесут датчик орегон заодно проверю вашу библиотеку. Если что напишу
Скажите я опробывал вашу бибилиотеку. И вот что получил:
и я так понял что она работает не так как я ожидал)) Можете пояснить что не так? Мой датчик THGN132N
Если брать общий скетч то он вроде все видит:
Нашел с описании функции в .cpp файле что это у Вас он выводит посылку:
Т.е. я так понял что он с посылке не может вытащить остальные значения так? или в чем дело? заранее спасибо
Крч за последние 20 мин не разу не вывел результат((( Я так понимаю в вашей бибиле же идут проверки пакетов и я так понял что не проходят проверки и кореляции как бы и поэтмоу не выводит так?
Честно скажу, не знаю в чём дело. Что-то похожее у меня было пару раз на одном из датчиков. Спасал сброс датчика.
Возможно идёт захват данных не с той частотой. Попробуйте поменять параметр LENGTH_TOLERANCE в ашнике. может поможет. Других мыслей пока нет
В том и дело я тоже ваш код иучил в cpp странно должно выводить но условие не выполняется по выводу значений. а вот исходный код под ООК работает. Если не разберусь могу остановиться на нем, но с ним не удобно он громоздкий. Да и опыта большого в библиотек перестраивать код у меня нет( У вас там стоит 20. Почему 20? и насколько можно попробывать поставить?
Сброс датчика не помог?
LENGTH_TOLERANCE - Допустимое отклонение мкс при поиске в эфире последоветельностей из трёх импульсов преамбулы. Если частота передачи данных датчика чуток отличается, то варьирование этого параметр поможет поймать пакет за хвост.
Ок попробую как с работы приду. Отпишу, мало ли может у кого такое же будет.
Крч все без результата((( Скажите госопда. А как можно использовать две функции одновременно по одному и тому же прерыванию со 2го пина? Т.е. мне надо чтобы моя дуня и слушала эфир на наличие данных от датчика и в тоже время слушала эфир спомощью библиотеки RS Switch от радио датчиков обычных дым, дверь и т.д. Пробывал в параллель вроде не пашет
извините был не прав. беру все обрано.
В общем все я вопросы порешал кроме как с библой поросенка чет не хочет((( Игрался я по всякому с LENGTH_TOLERANCE. датчик перезагружал. И нифига( Свой вопрос по поводу одновременной работы двых библиотек решил так. Просто вторую подключил на прерыванию (1) и все заработало. Если есть идеи по поводу библиотеки поросенка, буду рад услышать. Спасибо
Ребят вопрос. Как можно в параллель данного кода в дуню закинуть отправку данных по nRF??? у меня когда я вставляю в loop или в функцию reportSerial. Виснет как я понял дуня и каждый раз заново выполняет void setup. Код который ниже у меня работает, но есть необходимост ьпринятые данные пересылать серверу по nRF. Сделано так по причине того что на сервере нет места под этот кусок кода) Память под завязку да и прерывания пины используются.
В reportSerial правильное место. Если виснет дебажте свой код, ищите где проблема.
Крч. У меня вроде то норм отправляет то перезапуск идет как бы то виснет. но все это связанно с nRF думаю дело в питании . Как соберу в норм пайке все потестирую еще. Жду платы с китая просто. Отпишу позже
Вопрос по основному коду который вначале темы. Кто может подсказать почему может происходить зависание функции reportSerial? Т.е. допустим. принял данные с одного датчика и потмо тишина не принимает больше? Цель какая. Я придумал как можно использовать неограниченное количество датчиков (теоритически). Суть такая: А скетче я создал массив для хранения ИД номеров датчиков. И функцию которая заполняет этот массив если он пустой теми ИД которые приходят и потом оперирует данными. Сут ьтакая мне надо получать данные от датчиков сигнализации + от датчиков Oregon и потом по радиоканалу но на частоте 2.4 с помощью nRF отправлять на другой блок управления. ВОт код
Я в ступоре. Пока никаких вариантов почему он вешается из за nRF((( Вроде все должно работать но. Вот как это выглядит в работе.
Скажите а в ваших библиотеках нет в коде какой либо перезагрузки предусмотренной? Ну типа если что то там происходит то надо ребутнуть дуню? У меня ваши библиотеки заработали стабильно. Нахимичил) Новсе равно передача по nRF данных вешает Arduino не ясно почему. даже без модуля nRF все виснит и перезагружается
Всем кому интересна поддержка других датчиков метеостанций, вот раскопал проект с их поддержкой, в нем есть описание протоколов. HAma и т.п.
https://wiki.pilight.org/auriol_protocol_v20.pdf
https://manual.pilight.org/ основной раздел Weather Stations
Еще для информации, прошивка под esp8266 принимающая датчики ORegon, у себя залил на WemosD1 mini . работает. http://serg22.ru/radio/esp8266/
Еще для информации, прошивка под esp8266 принимающая датчики ORegon, у себя залил на WemosD1 mini . работает. http://serg22.ru/radio/esp8266/
Вот бы код посмотреть. Я так и не смог решить проблему с пропусками сигналов от приемника. У меня получилось, что обработка прерываний по ноге от приемника совершенно не гарантируется при работе WiFi...
я писал разработчику на форуме http://kazus.ru/forums/showthread.php?t=111260&page=20 но он пока не видит смысла ни в изменениях ни в открытии кода
с другой стороны, если не нужна 100% точность приема, то и нормально. я правда думаю себе заказать приемники на Telecontrolli https://www.electronshik.ru/item/rrq3-433-163578 супергетеродинные, длжно получше быть и антена штырь есть
Вот бы код посмотреть. Я так и не смог решить проблему с пропусками сигналов от приемника. У меня получилось, что обработка прерываний по ноге от приемника совершенно не гарантируется при работе WiFi...
А зачем нужен гарантированный прием от погодных датчиков?
Ведь для слежения за погодой не нужны мгновенные данные.
Я использую библиотек blynk и от поросенка для чтения датчиков. Плюс к самой есп подключен датчик BMP280 и геркон для подсчета оборотов хомячкового колеса.
Все более/менее на макете работает, правда пришлось разные временные задержки устанавливать для передачи данных блинком в сеть разными пакетами иначе при передачи данных одним пакетом отваливался контролер от сети постоянно. Еще при передачи пакетов пришлось отключать прерывание приемника. Т.е. периодически приеменик отключается, при этом нет сильно больших промежутков между приемами данных (не больше 10 мин.)
зы.
Хомяк, попался спортивный. Иногда за сутки 7 км пробегает.
думаю он пользовался исходниками отсюда : https://code.google.com/archive/p/osrf2com/
камеры нет, обозревающий хомяка?? друг так за крысой наблюдал он-лайн ;)
камеры нет, обозревающий хомяка?? друг так за крысой наблюдал он-лайн ;)
камеры нет, бегает сволочь только ночью при выключенном свете. Я думал, что он ленивый, а он просто стеснительный))
не смотрели исходники??
еще один эмулятор датчика орегон, на сей раз австралийский http://osengr.org/Projects/Canberra-Wireless-Sensor/Canberra-Wireless-Sensor.shtml