Подскажите, пожалуйста, почему выше приведенный скетч работает ТОЛЬКО на 2 цифровом пине? При указании другого пина сигнал не читается, как будто его вообще нет. :(
Подскажите, пожалуйста, почему выше приведенный скетч работает ТОЛЬКО на 2 цифровом пине? При указании другого пина сигнал не читается, как будто его вообще нет. :(
я не гуру, но я отвечу :)
Потому что на втором пине доступны прерывания:
Внешнее прерывание: 2 и 3. Данные выводы могут быть сконфигурированы на вызов прерывания либо на младшем значении,
либо на переднем или заднем фронте, или при изменении значения.
Подробная информация находится в описании функции attachInterrupt().
Внешнее прерывание: 2 и 3. Данные выводы могут быть сконфигурированы на вызов прерывания либо на младшем значении,
либо на переднем или заднем фронте, или при изменении значения.
Подробная информация находится в описании функции attachInterrupt().
Есть замечательные железки на чипе SI4432 (готовый модуль RF22), поддерживает разные модуляции и частоты, есть готовая библиотека для Arduino.
Хороший модуль, мощьный, дальнобойный (с приличной антенной на несколько километров лупит). Для чего его использовать не принципиально, только учтите что он весьма прожорливый, если нужно автономное питание.
В общем, часы тикают и отображаются, а вот температура нет. По отдельности если закоментить вывод часов- все ок. переносил вывод температуры в глобальную переменную нарвался на отображение температуры в увеличенном в 2 раза размере. Как праивлно сделать вывод ??? Спасибо
Сталкивался с такой же проблемой. Понял, что если в loop вызывается тяжелая процедура, то сигнал с датчика часто не успевает считася.
сделайте вызов printTime(); раз в секунду например, все должно заработать.
увы, полином найти не удалось. если счастливый обладатель датчика предоставит посылки отличающиеся одним битом можно будет закодировать crc порождающей матрицей.
Продолжая тему, если кому интересно сделал веб серверок с отображением датчиков орегоновских. отличие - основной код вынесен в библиотеки. Пришлось так сделать, из-за понятности и структурности кода. В планах сделать страничку загружаемую с SD карты с нормлаьным оформлением. в UNO занимает 16кб, есть еще куда дописать.
// 2012-09-06 - Oregon V2 decoder modified - Olivier Lebrun <olivier.lebrun@connectingstuff.net>
// 2012-06-21 - Oregon V2 decoder added - Dominique Pierre (zzdomi)
// 2012-06-21 - Oregon V3 decoder revisited - Dominique Pierre (zzdomi)
// New code to decode OOK signals from weather sensors, etc.
// 2010-04-11 Jean-Claude Wippler <jcw@equi4.com>
#include "DecodeOOK.h"
#include "OregonDecoderV1.h"
#include "OregonDecoderV2.h"
#include "OregonDecoderV3.h"
#include <Ethernet.h>
//433
OregonDecoderV1 orscV1;
OregonDecoderV2 orscV2;
OregonDecoderV3 orscV3;
// MAC address from Ethernet shield sticker under board
byte mac[] = { 0xDE, 0xAD, 0xAE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 100);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(81); // create a server at port 80
/// переменные для записи значений с датчиков
#define PORT 2
byte b_hum[3],b_bat[3],b_type[3];
float f_temp[3];
unsigned int i_Counter[4];
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;
}
///просто голый код
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.println();
decoder.resetDecoder();
}
// вывод данных по орегоновским сенсорам
void reportSerial2 (const char* s, class DecodeOOK& decoder) {
byte pos;
const byte* data = decoder.getData(pos);
//выводит тип декодера
Serial.print(s);
Serial.print(F(" "));
//выводим голый принятый код
// for (byte i = 0; i < pos; ++i) {
// Serial.print(data[i] >> 4, HEX);
// Serial.print(data[i] & 0x0F, HEX);
// }
Serial.print(F(": "));
// Outside/Water Temp : THGN132N,...
if(data[0] == 0x1A && data[1] == 0x2D)
{
Serial.print(F("Type:"));
Serial.print(data[0], HEX);
Serial.print(data[1], HEX);
Serial.print(F(", ID:"));
Serial.print(data[3], HEX);
Serial.print(F(", Channel:"));
Serial.print(channel(data));
Serial.print(F(", temp:"));
Serial.print(temperature(data));
Serial.print(F(", hum:"));
Serial.print(humidity(data));
Serial.print(F(", bat:"));
Serial.println(battery(data));
}
// Outside/Water Temp : THN132N,...
if(data[0] == 0xEA && data[1] == 0x4C)
{
Serial.print(F("Type:"));
Serial.print(data[0], HEX);
Serial.print(data[1], HEX);
Serial.print(F(", ID:"));
Serial.print(data[3], HEX);
Serial.print(F(", Channel:"));
Serial.print(channel(data));
Serial.print(F(", temp:"));
Serial.print(temperature(data));
Serial.print(F(", hum:"));
Serial.print(humidity(data));
Serial.print(F(", bat:"));
Serial.println(battery(data));
}
if // Inside Temp-Hygro : THGR-810,...
(data[0] == 0xFA && data[1] == 0x28)
{
Serial.print(F("Type:"));
Serial.print(data[0], HEX);
Serial.print(data[1], HEX);
Serial.print(F(", ID:"));
Serial.print(data[3], HEX);
Serial.print(F(", Channel:"));
Serial.print(channel(data));
Serial.print(F(", temp:"));
Serial.print(temperature(data));
Serial.print(F(", hum:"));
Serial.print(humidity(data));
Serial.print(F(", bat:"));
Serial.println(battery(data));
}
if (channel(data) > 0 && channel(data) < 4){
f_temp[channel(data)-1] = temperature(data);
b_hum[channel(data)-1] = humidity(data);
b_bat[channel(data)-1] = battery(data);
b_type[channel(data)-1] = (data[3]);
i_Counter[channel(data)-1]++;
//тут пытаемся записать в массив имя датчика в строке
}
decoder.resetDecoder();
}
void setup () {
Serial.begin(115200);
Serial.println("\n[ookDecoder]");
Ethernet.begin(mac, ip);
server.begin();
//attach our interrupt handler on port int1 (arduino uno port2)
attachInterrupt(0, ext_int_1, CHANGE);
proc_ClearVar();
}
void loop () {
static int i = 0;
cli();
word p = pulse;
pulse = 0;
sei();
//433Mhz
if (p != 0) {
// Serial.println(p); // Печать что есть на выходе приемника
if (orscV1.nextPulse(p))
reportSerial2("OSV1", orscV1);
if (orscV2.nextPulse(p))
reportSerial2("OSV2", orscV2);
if (orscV3.nextPulse(p))
reportSerial("OSV3", orscV3);
}
listenForEthernetClients();
}
void proc_ClearVar(){
for(byte x=0; x<=2; x++){
f_temp[x] = 0;
b_hum[x] = 0;
b_bat[x] = 0;
b_type[x]= 0;
}
}
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);
}
// Ne retourne qu'un apercu de l'etat de la baterie : 10 = faible
byte battery(const byte* data)
{
return (data[4] & 0x4) ? 10 : 100;
}
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;
}
return channel;
}
void listenForEthernetClients() {
// listen for incoming clients
EthernetClient client = server.available();
if (client) {
Serial.println("Got a client");
// an http request ends with a blank line
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
// if you've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
if (c == '\n' && currentLineIsBlank) {
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
client.print("<body style=background-color:bisque>"); //set background to white
client.println("<font color='red'><h1>Meteostation</font></h1>");
client.println();
client.println("<br />");
//тут сделать в цикле из сущестующего массива
for (int tx = 0; tx < 3; tx++){
client.println();
client.print("Sensor N : ");
client.println(tx);
client.println("<br />");
client.print("Sensor ID : ");
client.println(b_type[tx],HEX);
client.println("<br />");
client.print(" temperature C : ");
client.println(f_temp[tx]);
client.println("<br />");
client.println("Gydro %: ");
client.println( b_hum[tx]);
client.println("<br />");
client.println("V batt ");
client.println( b_bat[tx]);
client.println("<br />");
client.println();
client.println("<br />");
}
break;
}
if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
}
else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
// give the web browser time to receive the data
delay(1);
// close the connection:
client.stop();
}
}
есть конечно. а по поводу esp8266 он шумит сильно, плохо на приемник влияет.. а так да, иделаьно-б было. ЕЩе вариант, если-б автор прошивки известной для esp8266 homes-smart.ru внес в нее чтение данных датчиков.
куда выложить-то?? тут чудной форум.. как в нем файлы-то прикреплять. А по автору прошивки, тут думаю материально надо его стимулировать.. + делать макетку для esp уменьшающую собственные шумы ( развяки по питанию, экраны и пр)
Добрый день ! такой вот модуль http://www.aliexpress.com/snapshot/6822989142.html?orderId=68533532401167 куплен и работает с антенной конечно , но иногда получает инфу орегона(THGN132N) с ошибками , причина не ясна. Код ведь используемый для приема чужой и он до конца не ясен. Сейчас использую в связке с Esp 8266-07. До этого с ардуино uno и приемник был вот этот http://www.aliexpress.com/snapshot/6425544719.html?orderId=65249433881167 ошибок не было ,но был прием плох мог раз за полчаса принять. В принципе esp стабильней работает и с интернетом соединение без дополнительных модулей, да и с прерываниями у нее лучше чем на ардуинке( на esp указываешь пин какой тебе нужен. Скетч можно компилировать и среды ардуино. P.S. фото если получится загружу
привет! в инструкции на амс пишут диапазон 795 – 1050mb, в исходниках декодеров давление вычисляется прибавлением к константе 856. кто может внести ясность?
я-б приемник экранировал.. а антенку использовал от рации на 433..
пробовал , пофиг, в скетче добавлена проверка приема данных, если разброс составит 5 гр. или 5% влажности между приемом значит ложь . За 40сек. между передачами так темп.и влажность скакануть не смогут.
В общем, часы тикают и отображаются, а вот температура нет. По отдельности если закоментить вывод часов- все ок. переносил вывод температуры в глобальную переменную нарвался на отображение температуры в увеличенном в 2 раза размере. Как праивлно сделать вывод ??? Спасибо
Сталкивался с такой же проблемой. Понял, что если в loop вызывается тяжелая процедура, то сигнал с датчика часто не успевает считася.
сделайте вызов printTime(); раз в секунду например, все должно заработать.
Добрый день!
Все верно. У меня раз в 10 минут обновляется дисплей, раз в 15 минут производится отправка данных на narodmon.ru. А часы метеостанции не нужны, имхо.
5) И самое главное - найти осциллографом или методом научного тыка временные интервалы для "TIME = 482". У меня три ардуины и у всех этот параметр пришлось подбирать индивидуально, из-за различий в работе внутреннего таймера. Приём на базе работает только если это время +/- 1-3 микросекунды от стандарта. Выключение прерываний сильно влияет на этот параметр, если их не выключать ардуина растягивает пакеты во времени на произвольное число и они не всегда понимаются базой. Если нет осциллографа можно попробовать перебрать по очереди все значения от 480-490... ;)
Кстати, представленный в первом посте код приёмника у меня "глуховат", почти не слышит датчики внешние, а вот тот что представлен в посте #113 вполне работает сносно, правда часто CRC в конце пакета не показывает, возможно из-за этого первый код и не работает... но тут уж я разбираться не стал, работает и ладно... ;)
Поделитесь опытом: кто какой приемник использует для приема орегоновских датчиков и как далеко они работают.
Мне бы добиться уверено приема на расстоянии 10 метров через пару гипсовых стен.
Экспериментировал с датчиками Oregon Scientific THN132N и таким копеечным приёмником
Если питать Arduino от USB, то без антенны приёмник ловит сигнал на расстоянии около 50 см, а с прикрученным куском провода около 17-18 см - на расстоянии около метра.
Если подать питание от адаптера на 12V, то происходит чудо — сигнал удаётся получить с расстояния >10 метров через три стены в панельном доме.
В процессе построения погодной станции на датчиках Oregon не смог на указанном здесь коде добиться нужной дальности приёма. Пришлось писать свой приёмник, а затем и передатчик . Думал разместить всё сюда, но решил создать отдельную тему. Всё-таки проект...
Чтоб работал прием с датчикав, надо использовать нормальный приемник. Дешёвые приёмники с али плохо настроены, видимо. У меня отличный прием в квартире через 2 толстые (60см) кирпичные стены 15метров по прямой. Приемник с али ловил в пределах 10см.
Я сравнивал дальность приёма приёмника с али и приёмника из погодной станции Oregon. Разницы не обнаружил. Да и по схеме они очень схожи, хотя орегоновский выполнен, конечно, солиднее. У него индуктивность входного контура выполнена дорожкой на плате.
Прикупил себе вот такую пару: приемник MX-RM-5V и передатчик FS1000A. Вместе они прекрасно работают, а вот сигнал с THN123N не ловится никак, ни с 10 см ни 10м. Сначала думал что мне попались модули на 315Mhz, но нет на кварце передатчика четко написано 433Mhz.
В идеале надо бы к выходу приёмника подключиться осциллографом, это дало ответы на все вопросы. Но понимаю, что далеко не у всех есть такая возможность. У меня была похожая ситуация в начале. Попробуйте загрузить мой скетч, установив #define RTC_PRESENT 0. Если приходят хоть какие-то импульсы с частотой 1024Гц, в Serial информация свалится. А там уж и видно будет, что не так.
На самом деле вы можете проверить непосредственно в скетче ловит ли приемник что либо: поставьте печать в консоль значения pulse как тут
Если приемник работает в консоль будет валиться куча байтов
Выглядит это как шум, шум, шум потом сигнал и опять шум. Причем сигнал меньше по аплитуде чем шум.
если сигнал мелкий - то частота не совпадает... или модуляция не АМ.
Выкладываю подчищенный скетч re3lex-а только под датчики. Надеюсь кому то пригодится:
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; } }; OregonDecoderV2 orscV2; // Объявляем переменные и константы const byte maxSensors = 3; // Максимальное количество регистрируемых сенсоров float pressure; // Давление unsigned long sensorID[maxSensors]; // Массив с идентификаторами сенсоров int sensorType[maxSensors]; // Массив с типами сенсоров byte sensorChannel[maxSensors]; // Массив с каналами сенсоров int sensorTemp[maxSensors]; // Массив с данными температуры от сенсоров byte sensorTempSign[maxSensors]; //Массив с признаком знака температуры byte sensorHum[maxSensors]; // Массив с данными влажности byte sensorHumStr[maxSensors]; // Массив с данными об условиях byte sensorBatteryStatus[maxSensors]; // Массив с данными о статусе батареи byte sensorDataUpdated[maxSensors]; // Массив с признаком обновления данных // Режим отладки (будет выводить на терминал) const boolean DEBUG = false; #define R_LED 13 // data receiving LED unsigned long r_ledNow = 0; unsigned long t_ledNow = 0; int errorDelay = 150; 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; } // Функция первичной обработки данных и регистрации сенсоров void reportSerial (const char* s, class DecodeOOK& decoder) { byte pos; const byte* data = decoder.getData(pos); if (DEBUG) { Serial.print(s); Serial.print(' '); } byte checksum = data[0] >> 4; for (byte i = 1; i < 8; ++i) { checksum += data[i] >> 4; checksum += data[i] & 0x0F; } //Проверяем контрольную сумму if (checksum == data[8]) { byte currentSensor = 255; byte lastRegisteredSensor = -1; unsigned long sensID = (unsigned long) data[0] << 16; sensID += (unsigned long) data[1] << 8; sensID += (unsigned long) data[3]; for (byte i = 0; i < maxSensors; ++i) { if (sensorID[i] == 0) { lastRegisteredSensor = i; break; } if (sensorID[i] == sensID) { currentSensor = i; break; } } //определяем канал byte channel; switch (data[2]){ case 0x10: channel = 1; break; case 0x20: channel = 2; break; case 0x40: channel = 3; break; } // Поискали сенсор, если не нашли до регистрируем его if (currentSensor == 255) { if (DEBUG) { Serial.print("New sensor detected with ID: "); Serial.println(sensID,HEX); Serial.print("Adding to system with Index: "); Serial.println(lastRegisteredSensor); } if(lastRegisteredSensor >= 0) { sensorID[lastRegisteredSensor] = sensID; currentSensor = lastRegisteredSensor; } else { if (DEBUG) { Serial.println("too many sensors. will not add this"); } return; } } //Заносим данные с сенсора по массивам sensorChannel[currentSensor] = channel; sensorType[currentSensor] = (data[0] << 8)+data[1]; switch (sensorType[currentSensor]) { // Для других типов сенсоров, придется тут добавить что-то своё case 0x1A2D: case 0xFA28: sensorTemp[currentSensor] = (data[5] >> 4)*100+(data[5] & 0x0F)*10+(data[4] >> 4); sensorTempSign[currentSensor] = 0; if((data[6] & 0x08) == 0x08) { sensorTempSign[currentSensor] = 1; } sensorHum[currentSensor] = (data[7] & 0x0F)*10+(data[6] >> 4); sensorHumStr[currentSensor] = data[7] >> 6; sensorBatteryStatus[currentSensor] = (data[4] & 0x04) >> 2; break; } sensorDataUpdated[currentSensor] = 1; if (DEBUG) { for (byte i = 0; i < pos; ++i) { Serial.print(data[i] >> 4, HEX); Serial.print(data[i] & 0x0F, HEX); } Serial.println(); } } else { if (DEBUG) { Serial.println("Checksum failed"); } } decoder.resetDecoder(); } void setup () { pinMode(2, INPUT); Serial.begin(9600); Serial.println("\n[Arduino Digital Home v2.0]"); attachInterrupt(0, ext_int_1, CHANGE); // Cleaning array with registered sensors for (byte i = 0; i < maxSensors; ++i) { sensorID[i] = 0; sensorDataUpdated[i] = 0; } pinMode(R_LED, OUTPUT); } void loop () { //static int i = 0; cli(); word p = pulse; pulse = 0; sei(); if (p != 0) { if (orscV2.nextPulse(p)) { sendDataSerial(); reportSerial("OSV2", orscV2); r_ledNow = millis()+200; digitalWrite(R_LED, HIGH); } } if (millis() >= r_ledNow) { digitalWrite(R_LED, LOW); } if (millis() >= t_ledNow) { } } // Функция вывода данных с сенсоров на терминал void sendDataSerial() { Serial.println("Data reporting begin"); Serial.println(" mmHg"); for (byte i = 0; i < maxSensors; ++i) { if ((sensorID[i] != 0) && (sensorDataUpdated[i] == 1)) { Serial.print("Sensor ID: "); Serial.println(sensorID[i],HEX); Serial.print(" Sensor channel: "); Serial.println(sensorChannel[i],HEX); Serial.print(" Sensor type: "); // Запуск специфичных для типа сенсора функций вывода данных switch (sensorType[i]) { case 0x1A2D: Serial.println("THGN-132N"); reportSensorTHSerial(i); break; case 0xFA28: Serial.println("THGR-810"); reportSensorTHSerial(i); break; default: Serial.println("Sensor is off-line"); } } sensorDataUpdated[i] = 0; } Serial.println("Data reporting end"); } void reportSensorTHSerial(byte sensorNum) { Serial.print(" Sensor temperature: "); if ((sensorTempSign[sensorNum] == 0) && (sensorTemp[sensorNum] != 0)) { Serial.print("+"); } if (sensorTempSign[sensorNum] == 1) { Serial.print("-"); } Serial.print(sensorTemp[sensorNum]/10); Serial.print("."); Serial.print(sensorTemp[sensorNum] - int(sensorTemp[sensorNum]/10)*10); Serial.println("C"); Serial.print(" Sensor humidity: "); Serial.print(sensorHum[sensorNum]); Serial.print("% - "); switch (sensorHumStr[sensorNum]) { case 0: Serial.println("normal"); break; case 1: Serial.println("comfort"); break; case 2: Serial.println("dry"); break; case 3: Serial.println("wet"); break; } if (sensorBatteryStatus[sensorNum] == 0) { Serial.println(" Battery level is good"); } else { Serial.println(" Battery level is low"); } }если сигнал мелкий - то частота не совпадает... или модуляция не АМ.
Спасибо, уже удалось запустить. :)
Уважаемые гуру!
Подскажите, пожалуйста, почему выше приведенный скетч работает ТОЛЬКО на 2 цифровом пине? При указании другого пина сигнал не читается, как будто его вообще нет. :(
Уважаемые гуру!
Подскажите, пожалуйста, почему выше приведенный скетч работает ТОЛЬКО на 2 цифровом пине? При указании другого пина сигнал не читается, как будто его вообще нет. :(
я не гуру, но я отвечу :)
Потому что на втором пине доступны прерывания:
http://arduino.ru/Hardware/ArduinoBoardUno
я не гуру, но я отвечу :)
Потому что на втором пине доступны прерывания:
http://arduino.ru/Hardware/ArduinoBoardUno
Точно! Спасибо!
Уже понял что это связано со строкой
attachInterrupt(1, ext_int_1, CHANGE);
Только что запустил на 3 пине. Теперь осталось на меге это запустить на пинах выше 23-го.
Интуитивно понял по строке из другого скетча:
mySwitch.enableReceive(0); // Receiver on inerrupt 0 => that is pin #2
Но что это прерывание думал бы еше долго. )))))
Похоже для меги максимум по прерываниям 18-21 пины.
А они у меня под TFT экраном и какие то уже зняты. Завтра попробую подлезть.
Есть замечательные железки на чипе SI4432 (готовый модуль RF22), поддерживает разные модуляции и частоты, есть готовая библиотека для Arduino.
Кто-то использовал такой модуль для приема и отправки данных для погодных датчиков?
Есть замечательные железки на чипе SI4432 (готовый модуль RF22), поддерживает разные модуляции и частоты, есть готовая библиотека для Arduino.
Хороший модуль, мощьный, дальнобойный (с приличной антенной на несколько километров лупит). Для чего его использовать не принципиально, только учтите что он весьма прожорливый, если нужно автономное питание.
Почему когда подключаю на arduino nano pin a0, d2 или d12 - не принимаются показания с датчика - на какой пин нужно вешать приемник ???
2 и 3 цифровые ноги судя по всему
2 и 3 цифровые ноги судя по всему
Да, работает только на пинах где есть прерываение.
char params[255]; 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; } }; 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; } }; OregonDecoderV2 orscV2; //////////////////////////////////// volatile word pulse; void oregonrd(void) { static word last; pulse = micros() - last; last += pulse; } 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); } // Ne retourne qu'un apercu de l'etat de la baterie : 10 = faible byte battery(const byte* data) { return (data[4] & 0x4) ? 10 : 90; } 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; } return channel; } ////////////////////////////////////////////////////////////////// String reportSerial(const char* s, class DecodeOOK& decoder) { byte pos; const byte* data = decoder.getData(pos); String vTemperatureData = ""; // Outside/Water Temp : THN132N,... if(data[0] == 0xEA && data[1] == 0x4C) { float tempC = temperature(data); char temp[5]; dtostrf(tempC,5,1,temp); sprintf(params,"deviceid=%s&channel=%i&themperature=%s&battery=%i","EA4C1083322340A3",channel(data),temp,battery(data)); vTemperatureData = params; } decoder.resetDecoder(); return vTemperatureData; } ////////////////////////////////////////////////////////////// void setup () { Serial.begin(57600); attachInterrupt(0, oregonrd, CHANGE); } void loop() { static int i = 0; cli(); word p = pulse; pulse = 0; sei(); if (p != 0) { if (orscV2.nextPulse(p)) { String vData = reportSerial("OSV2", orscV2); Serial.println(vData); } } } Использую такой код - в выводе deviceid=EA4C1083322340A3&channel=1&themperature= 27.9&battery=90 28016 и все больше не меняетсяВсем привет. В общем прошло много времени уже с момента подключения oregon датчика. Собственно по теме: подключил дисплей 16x2 + RTC + 433 приемник. Код брал отсюда https://github.com/onlinux/OWL-CM180/blob/6d47a1003ffe4d00a5d72f01ffb347... весь не буду выкладывать.
Вот мой код переделанный:
//*****УСТАНОВКА ВРЕМЕНИ ЧЕРЕЗ DS1307RTC #include "Wire.h" #define DS1307_I2C_ADDRESS 0x68 #include <LiquidCrystal.h> LiquidCrystal lcd(4, 5, 10, 11, 12, 13); //#define DISABLE_DEBUG // если нужен вывод в Serial - закомментируйте эту строчку byte decToBcd(byte val) { return ( (val/10*16) + (val%10) ); } byte bcdToDec(byte val) { return ( (val/16*10) + (val%16) ); } void setDateDs1307(byte second, // 0-59 byte minute, // 0-59 byte hour, // 1-23 byte dayOfWeek, // 1-7 byte dayOfMonth, // 1-28/29/30/31 byte month, // 1-12 byte year) // 0-99 { Wire.beginTransmission(DS1307_I2C_ADDRESS); Wire.write(0); Wire.write(decToBcd(second)); Wire.write(decToBcd(minute)); Wire.write(decToBcd(hour)); Wire.write(decToBcd(dayOfWeek)); Wire.write(decToBcd(dayOfMonth)); Wire.write(decToBcd(month)); Wire.write(decToBcd(year)); Wire.endTransmission(); } void getDateDs1307(byte *second, byte *minute, byte *hour, byte *dayOfWeek, byte *dayOfMonth, byte *month, byte *year) { Wire.beginTransmission(DS1307_I2C_ADDRESS); Wire.write(0); Wire.endTransmission(); Wire.requestFrom(DS1307_I2C_ADDRESS, 7); *second = bcdToDec(Wire.read() & 0x7f); *minute = bcdToDec(Wire.read()); *hour = bcdToDec(Wire.read() & 0x3f); *dayOfWeek = bcdToDec(Wire.read()); *dayOfMonth = bcdToDec(Wire.read()); *month = bcdToDec(Wire.read()); *year = bcdToDec(Wire.read()); } class DecodeOOK { ......................................................... ......................................................... }; //=================================================================== class OregonDecoderV3 : public DecodeOOK { public: ........................................ ........................ }; //=================================================================== OregonDecoderV2 orscV2; OregonDecoderV3 orscV3; volatile word pulse; void ext_int_1(void) { ..................................... ...................................... } void reportSerial (const char* s, class DecodeOOK& decoder) { byte pos; const byte* data = decoder.getData(pos); #ifndef DISABLE_DEBUG Serial.print(s); Serial.print(' '); for (byte i = 0; i < pos; ++i) { Serial.print(data[i] >> 4, HEX); Serial.print(data[i] & 0x0F, HEX); } #endif // Energy OWL : CMR180 if(data[2] == 0x3C ) { #ifndef DISABLE_DEBUG Serial.print("[CMR180,...] Id:"); Serial.print(data[0], HEX);Serial.print(data[1], HEX); Serial.print(", size:"); Serial.print(pos); Serial.print(" ,Flags:"); Serial.print(data[3] & 0x0F, HEX); Serial.print(" ,power:"); Serial.print(power(data)); if (pos > 6) { // Display only for main frame // Secondary frame is only 6 Bytes long Serial.print(" ,total:"); Serial.print(total(data)); Serial.print(" ,total kWh:"); Serial.print(total(data)/3600/1000); } Serial.println(); #endif } // Outside/Water Temp : THN132N,... if (data[0] == 0xEA && data[1] == 0x4C) { #ifndef DISABLE_DEBUG Serial.print("[THN132N,...] Id:"); Serial.print(data[3], HEX); Serial.print(" ,Channel:"); Serial.print(channel(data)); Serial.print(" ,temp:"); Serial.print(temperature(data)); Serial.print(" ,bat:"); Serial.print(battery(data)); Serial.println(); #endif lcd.setCursor(0, 0); lcd.print("temp:"); // вывод на экран температуры lcd.setCursor(5, 0); lcd.print(temperature(data)); lcd.setCursor(10, 0); lcd.print("\x99"); } // Inside Temp-Hygro : THGR228N,... else if(data[0] == 0x1A && data[1] == 0x2D) { #ifndef DISABLE_DEBUG Serial.print("[THGR228N,...] Id:"); Serial.print(data[3], HEX); Serial.print(" ,Channel:"); Serial.print(channel(data)); Serial.print(" ,temp:"); Serial.print(temperature(data)); Serial.print(" ,hum:"); Serial.print(humidity(data)); Serial.print(" ,bat:"); Serial.print(battery(data)); Serial.println(); #endif } decoder.resetDecoder(); } void setup () { byte second, minute, hour, dayOfWeek, dayOfMonth, month, year; Wire.begin(); second = 30; minute = 00; hour = 23; dayOfWeek = 7; dayOfMonth = 17; month = 5; year = 15; // setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year); #ifndef DISABLE_DEBUG Serial.begin(115200); Serial.println("\n[ookDecoder]"); #endif lcd.begin(16, 2); attachInterrupt(0, ext_int_1, CHANGE); //DDRE &= ~_BV(PE5); //input with pull-up //PORTE &= ~_BV(PE5); } void loop () { printTime(); static int i = 0; cli(); word p = pulse; pulse = 0; sei(); if (p != 0) { if (orscV3.nextPulse(p)) reportSerial("OSV3", orscV3); if (orscV2.nextPulse(p)) reportSerial("OSV2", orscV2); } } void printTime() { byte second, minute, hour, dayOfWeek, dayOfMonth, month, year; getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year); lcd.setCursor(0, 1); lcd.print(hour); lcd.setCursor(2, 1); lcd.print(":"); lcd.setCursor(3, 1); lcd.print(minute); lcd.setCursor(5, 1); lcd.print(":"); lcd.print(second); lcd.setCursor(7, 0); lcd.print(dayOfMonth); lcd.setCursor(8, 0); lcd.print("/"); lcd.setCursor(9, 0); lcd.print(month); lcd.setCursor(11, 0); lcd.print("/"); lcd.setCursor(12, 0); lcd.print(year); } В общем, часы тикают и отображаются, а вот температура нет. По отдельности если закоментить вывод часов- все ок. переносил вывод температуры в глобальную переменную нарвался на отображение температуры в увеличенном в 2 раза размере. Как праивлно сделать вывод ??? СпасибоНу вот тишина (((( А вроде на вид не сложно ...
В общем, часы тикают и отображаются, а вот температура нет. По отдельности если закоментить вывод часов- все ок. переносил вывод температуры в глобальную переменную нарвался на отображение температуры в увеличенном в 2 раза размере. Как праивлно сделать вывод ??? Спасибо
Сталкивался с такой же проблемой. Понял, что если в loop вызывается тяжелая процедура, то сигнал с датчика часто не успевает считася.
сделайте вызов printTime(); раз в секунду например, все должно заработать.
Доброго вечера, уважаемые форумчане!
А эмуляцию Орегоновских датчиков никто не реализовал?
какой версии протокола?
Датчик типа THGN132N по моему 2 версия протокола.
увы, полином найти не удалось. если счастливый обладатель датчика предоставит посылки отличающиеся одним битом можно будет закодировать crc порождающей матрицей.
Эмулятор из самого первого поста использует 2 версию, он работает у вас?
Попробуй код отсюда https://github.com/onlinux/OWL-CM180/blob/6d47a1003ffe4d00a5d72f01ffb3477ba8083a4e/arduino/oregon_owl.ino
Привет! У меня такой датчки Assistant AH-1976
Я вижу, что я с него сигнал получаю, но данные вытащить не могу. Видео на YouTobe https://youtu.be/kDhrJ00as0Y
Скетч взял этот: http://arduino.ru/forum/proekty/chtenie-i-emulyatsiya-datchikov-oregon-scientific-433mhz?page=2#comment-143544 и дописал в него вывод пульс.
Что выводит pulse ? Что значут эти цифры?
Я так понимаю, что декодер под него не подходит и по этому я на выходе нечего нее вижу.
Есть смысл с ним мучатся или проще свой датчик на Arduino сделать?
P.S. На видео с лева SDR которая читает данные с китайского ТВ тюнера DVB-T вот такого вот: http://ru.aliexpress.com/item/USB2-0-DAB-FM-DVB-T-RTL2832-R820T-SDR-RTL-SDR-Dongle-Stick-Digital-TV-Tuner/32267130430.html
это же не орегон, и что он там шлет только китайцам известно.
Пульс- это оцифрованный сигнал, полученный за время прерывания
Спасибо! Понял, что декоддировать не выйдет и лучше делать свой датчик на Arduino или ESP8266
Продолжая тему, если кому интересно сделал веб серверок с отображением датчиков орегоновских. отличие - основной код вынесен в библиотеки. Пришлось так сделать, из-за понятности и структурности кода. В планах сделать страничку загружаемую с SD карты с нормлаьным оформлением. в UNO занимает 16кб, есть еще куда дописать.
// 2012-09-06 - Oregon V2 decoder modified - Olivier Lebrun <olivier.lebrun@connectingstuff.net> // 2012-06-21 - Oregon V2 decoder added - Dominique Pierre (zzdomi) // 2012-06-21 - Oregon V3 decoder revisited - Dominique Pierre (zzdomi) // New code to decode OOK signals from weather sensors, etc. // 2010-04-11 Jean-Claude Wippler <jcw@equi4.com> #include "DecodeOOK.h" #include "OregonDecoderV1.h" #include "OregonDecoderV2.h" #include "OregonDecoderV3.h" #include <Ethernet.h> //433 OregonDecoderV1 orscV1; OregonDecoderV2 orscV2; OregonDecoderV3 orscV3; // MAC address from Ethernet shield sticker under board byte mac[] = { 0xDE, 0xAD, 0xAE, 0xEF, 0xFE, 0xED }; IPAddress ip(192, 168, 1, 100); IPAddress gateway(192, 168, 1, 1); IPAddress subnet(255, 255, 255, 0); // Initialize the Ethernet server library // with the IP address and port you want to use // (port 80 is default for HTTP): EthernetServer server(81); // create a server at port 80 /// переменные для записи значений с датчиков #define PORT 2 byte b_hum[3],b_bat[3],b_type[3]; float f_temp[3]; unsigned int i_Counter[4]; 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; } ///просто голый код 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.println(); decoder.resetDecoder(); } // вывод данных по орегоновским сенсорам void reportSerial2 (const char* s, class DecodeOOK& decoder) { byte pos; const byte* data = decoder.getData(pos); //выводит тип декодера Serial.print(s); Serial.print(F(" ")); //выводим голый принятый код // for (byte i = 0; i < pos; ++i) { // Serial.print(data[i] >> 4, HEX); // Serial.print(data[i] & 0x0F, HEX); // } Serial.print(F(": ")); // Outside/Water Temp : THGN132N,... if(data[0] == 0x1A && data[1] == 0x2D) { Serial.print(F("Type:")); Serial.print(data[0], HEX); Serial.print(data[1], HEX); Serial.print(F(", ID:")); Serial.print(data[3], HEX); Serial.print(F(", Channel:")); Serial.print(channel(data)); Serial.print(F(", temp:")); Serial.print(temperature(data)); Serial.print(F(", hum:")); Serial.print(humidity(data)); Serial.print(F(", bat:")); Serial.println(battery(data)); } // Outside/Water Temp : THN132N,... if(data[0] == 0xEA && data[1] == 0x4C) { Serial.print(F("Type:")); Serial.print(data[0], HEX); Serial.print(data[1], HEX); Serial.print(F(", ID:")); Serial.print(data[3], HEX); Serial.print(F(", Channel:")); Serial.print(channel(data)); Serial.print(F(", temp:")); Serial.print(temperature(data)); Serial.print(F(", hum:")); Serial.print(humidity(data)); Serial.print(F(", bat:")); Serial.println(battery(data)); } if // Inside Temp-Hygro : THGR-810,... (data[0] == 0xFA && data[1] == 0x28) { Serial.print(F("Type:")); Serial.print(data[0], HEX); Serial.print(data[1], HEX); Serial.print(F(", ID:")); Serial.print(data[3], HEX); Serial.print(F(", Channel:")); Serial.print(channel(data)); Serial.print(F(", temp:")); Serial.print(temperature(data)); Serial.print(F(", hum:")); Serial.print(humidity(data)); Serial.print(F(", bat:")); Serial.println(battery(data)); } if (channel(data) > 0 && channel(data) < 4){ f_temp[channel(data)-1] = temperature(data); b_hum[channel(data)-1] = humidity(data); b_bat[channel(data)-1] = battery(data); b_type[channel(data)-1] = (data[3]); i_Counter[channel(data)-1]++; //тут пытаемся записать в массив имя датчика в строке } decoder.resetDecoder(); } void setup () { Serial.begin(115200); Serial.println("\n[ookDecoder]"); Ethernet.begin(mac, ip); server.begin(); //attach our interrupt handler on port int1 (arduino uno port2) attachInterrupt(0, ext_int_1, CHANGE); proc_ClearVar(); } void loop () { static int i = 0; cli(); word p = pulse; pulse = 0; sei(); //433Mhz if (p != 0) { // Serial.println(p); // Печать что есть на выходе приемника if (orscV1.nextPulse(p)) reportSerial2("OSV1", orscV1); if (orscV2.nextPulse(p)) reportSerial2("OSV2", orscV2); if (orscV3.nextPulse(p)) reportSerial("OSV3", orscV3); } listenForEthernetClients(); } void proc_ClearVar(){ for(byte x=0; x<=2; x++){ f_temp[x] = 0; b_hum[x] = 0; b_bat[x] = 0; b_type[x]= 0; } } 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); } // Ne retourne qu'un apercu de l'etat de la baterie : 10 = faible byte battery(const byte* data) { return (data[4] & 0x4) ? 10 : 100; } 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; } return channel; } void listenForEthernetClients() { // listen for incoming clients EthernetClient client = server.available(); if (client) { Serial.println("Got a client"); // an http request ends with a blank line boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { char c = client.read(); // if you've gotten to the end of the line (received a newline // character) and the line is blank, the http request has ended, // so you can send a reply if (c == '\n' && currentLineIsBlank) { // send a standard http response header client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println(); client.print("<body style=background-color:bisque>"); //set background to white client.println("<font color='red'><h1>Meteostation</font></h1>"); client.println(); client.println("<br />"); //тут сделать в цикле из сущестующего массива for (int tx = 0; tx < 3; tx++){ client.println(); client.print("Sensor N : "); client.println(tx); client.println("<br />"); client.print("Sensor ID : "); client.println(b_type[tx],HEX); client.println("<br />"); client.print(" temperature C : "); client.println(f_temp[tx]); client.println("<br />"); client.println("Gydro %: "); client.println( b_hum[tx]); client.println("<br />"); client.println("V batt "); client.println( b_bat[tx]); client.println("<br />"); client.println(); client.println("<br />"); } break; } if (c == '\n') { // you're starting a new line currentLineIsBlank = true; } else if (c != '\r') { // you've gotten a character on the current line currentLineIsBlank = false; } } } // give the web browser time to receive the data delay(1); // close the connection: client.stop(); } }а сами библиотеки есть?
PS оптимально вообще адаптировать код под ESP8266 и лить данные по WIFI :)
есть конечно. а по поводу esp8266 он шумит сильно, плохо на приемник влияет.. а так да, иделаьно-б было. ЕЩе вариант, если-б автор прошивки известной для esp8266 homes-smart.ru внес в нее чтение данных датчиков.
выложите пожалуйста, ок?
попробуйте написать автору, может добавит тоже
куда выложить-то?? тут чудной форум.. как в нем файлы-то прикреплять. А по автору прошивки, тут думаю материально надо его стимулировать.. + делать макетку для esp уменьшающую собственные шумы ( развяки по питанию, экраны и пр)
Добрый день ! такой вот модуль http://www.aliexpress.com/snapshot/6822989142.html?orderId=68533532401167 куплен и работает с антенной конечно , но иногда получает инфу орегона(THGN132N) с ошибками , причина не ясна. Код ведь используемый для приема чужой и он до конца не ясен. Сейчас использую в связке с Esp 8266-07. До этого с ардуино uno и приемник был вот этот http://www.aliexpress.com/snapshot/6425544719.html?orderId=65249433881167 ошибок не было ,но был прием плох мог раз за полчаса принять. В принципе esp стабильней работает и с интернетом соединение без дополнительных модулей, да и с прерываниями у нее лучше чем на ардуинке( на esp указываешь пин какой тебе нужен. Скетч можно компилировать и среды ардуино. P.S. фото если получится загружу

я-б приемник экранировал.. а антенку использовал от рации на 433..
Кто сможет помочь с выводом температуры с датчика орегон большими цифрами? Код есть сделал по этой статье https://geektimes.ru/post/255812/ , сам код просто очень большой получился - вот исходник https://cloud.mail.ru/public/KGdN/8QA7A3zx7 . В интернете ничего толкого не нашел. ((
Компилятор ругается так:
Big_LCD.ino: In function 'void reportSerial(const char*, DecodeOOK&)':
Big_LCD:491: error: at this point in file"
Ну вот (((
привет! в инструкции на амс пишут диапазон 795 – 1050mb, в исходниках декодеров давление вычисляется прибавлением к константе 856. кто может внести ясность?
Пробовал
я-б приемник экранировал.. а антенку использовал от рации на 433..
пробовал , пофиг, в скетче добавлена проверка приема данных, если разброс составит 5 гр. или 5% влажности между приемом значит ложь . За 40сек. между передачами так темп.и влажность скакануть не смогут.
В общем, часы тикают и отображаются, а вот температура нет. По отдельности если закоментить вывод часов- все ок. переносил вывод температуры в глобальную переменную нарвался на отображение температуры в увеличенном в 2 раза размере. Как праивлно сделать вывод ??? Спасибо
Сталкивался с такой же проблемой. Понял, что если в loop вызывается тяжелая процедура, то сигнал с датчика часто не успевает считася.
сделайте вызов printTime(); раз в секунду например, все должно заработать.
Добрый день!
Все верно. У меня раз в 10 минут обновляется дисплей, раз в 15 минут производится отправка данных на narodmon.ru. А часы метеостанции не нужны, имхо.
Добрый день!
Все верно. У меня раз в 10 минут обновляется дисплей, раз в 15 минут производится отправка данных на narodmon.ru. А часы метеостанции не нужны, имхо.
У меня это не просто метеостнция. Этот блок у меня ка основной для умного дома.
Если интересно:
https://www.youtube.com/watch?v=rQ4M4hDmMoA&index=1&list=PL2wwtsKwVVjL-t...
Подскажите, взял код передатчика из первого поста эмуляции орегона, всё подключил но база ничего не показывает.
Хотя в эфир всё уходит, проверял через код приёмника. У кого получилось эмулировать датчик для базы?
В общем код из шапки поста неполный, надо его чуток дохачивать...
1) Кроме чексуммы восьмого байта ещё и CRC считать в девятом байте пакета.
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; }Заменив старую функцию новой
2) Увеличить размер буфера с 9 на 10 из-за CRC.
3) Увеличить размер тишины между посылками delayMicroseconds(TWOTIME*10); хотя это и не обязательно, обычно база читает только первый посыл.
4) защитить код передатчика от прерываний
void sendOregon(byte *data, byte size) { cli(); //off sendPreamble(); //sendSync(); sendData(data, size); //sendPostamble(); sei(); //on }5) И самое главное - найти осциллографом или методом научного тыка временные интервалы для "TIME = 482". У меня три ардуины и у всех этот параметр пришлось подбирать индивидуально, из-за различий в работе внутреннего таймера. Приём на базе работает только если это время +/- 1-3 микросекунды от стандарта. Выключение прерываний сильно влияет на этот параметр, если их не выключать ардуина растягивает пакеты во времени на произвольное число и они не всегда понимаются базой. Если нет осциллографа можно попробовать перебрать по очереди все значения от 480-490... ;)
Кстати, представленный в первом посте код приёмника у меня "глуховат", почти не слышит датчики внешние, а вот тот что представлен в посте #113 вполне работает сносно, правда часто CRC в конце пакета не показывает, возможно из-за этого первый код и не работает... но тут уж я разбираться не стал, работает и ладно... ;)
Поделитесь опытом: кто какой приемник использует для приема орегоновских датчиков и как далеко они работают.
Мне бы добиться уверено приема на расстоянии 10 метров через пару гипсовых стен.
Экспериментировал с датчиками Oregon Scientific THN132N и таким копеечным приёмником
Если питать Arduino от USB, то без антенны приёмник ловит сигнал на расстоянии около 50 см, а с прикрученным куском провода около 17-18 см - на расстоянии около метра.
Если подать питание от адаптера на 12V, то происходит чудо — сигнал удаётся получить с расстояния >10 метров через три стены в панельном доме.
В процессе построения погодной станции на датчиках Oregon не смог на указанном здесь коде добиться нужной дальности приёма. Пришлось писать свой приёмник, а затем и передатчик . Думал разместить всё сюда, но решил создать отдельную тему. Всё-таки проект...
http://arduino.ru/forum/proekty/pogodnaya-stantsiya-na-datchikakh-oregon...
Чтоб работал прием с датчикав, надо использовать нормальный приемник. Дешёвые приёмники с али плохо настроены, видимо. У меня отличный прием в квартире через 2 толстые (60см) кирпичные стены 15метров по прямой. Приемник с али ловил в пределах 10см.
Я сравнивал дальность приёма приёмника с али и приёмника из погодной станции Oregon. Разницы не обнаружил. Да и по схеме они очень схожи, хотя орегоновский выполнен, конечно, солиднее. У него индуктивность входного контура выполнена дорожкой на плате.
Прикупил себе вот такую пару: приемник MX-RM-5V и передатчик FS1000A. Вместе они прекрасно работают, а вот сигнал с THN123N не ловится никак, ни с 10 см ни 10м. Сначала думал что мне попались модули на 315Mhz, но нет на кварце передатчика четко написано 433Mhz.
В чем может быть причина???
В идеале надо бы к выходу приёмника подключиться осциллографом, это дало ответы на все вопросы. Но понимаю, что далеко не у всех есть такая возможность. У меня была похожая ситуация в начале. Попробуйте загрузить мой скетч, установив #define RTC_PRESENT 0. Если приходят хоть какие-то импульсы с частотой 1024Гц, в Serial информация свалится. А там уж и видно будет, что не так.
А где, собственно, ваш скетч?