![]() |
|
|
|
|
#1 |
|
Administrator
Регистрация: 12.04.2010
Адрес: Москва
Сообщений: 9,618
Вес репутации: 9824 ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
В проекте используются
Arduino Nano v.7 Модуль приемника RF 433mHz Беспроводной датчик THGN132N от метеостанции Oregon Датчики THGN132N продаются в комплекте с метеостанциями Oregon, а так же их можно приобрести отдельно. Они позволяют измерять температуру и влажность, работают в широком температурном диапазоне (-40.0°C до +70.0°C), при этом точность измерения температуры — 0.1°C. Для изготовления антенны к модулю приемника нужно использовать одножильный провод длиной 17см(четверть волны) или 34 см(половина волны) Для компактности провод можно навить на круглый карандаш или ручку Подключаем по схеме Сигнал DATA с приемника, подключаем на пин D2 Ардуино Заливаем код в ардуино Код:
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);
}
}
}
Так как датчик имеет несколько каналов, а приемник возможно настроен на другой канал Еще имейте ввиду датчик OREGON отправляет свои показания примерно один раз в минуту После того как в сериал мониторе появятся показания температуры и влажности отнесите датчик на 3 метра и подождите пока датчик отправит следующие показания Если данные не приходят, то переключите на датчике другой канал и повторите все с начала. Можно так же подстроить контур RF433 приемника под Ваш датчик Oregon Для этого нужно к выходу приемника Data подключить пьезоизлучатель ЗП-1, ЗП-22, ЗП-4 или что то подобное Нажимая и отпуская кнопку сброс на датчике Oregon, вы должны услышать как звучит переданный датчиком пакет данных Подстраивая контур приемника, Вы должны ориентироваться на отчетливое звучание принимаемого пакета |
|
|
|
|
|
#2 |
|
Member
Регистрация: 23.11.2012
Сообщений: 47
Вес репутации: 186 ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Предлагаю вниманию использование датчиков от целого ряда метеостанций.
Используется: Датчик температуры: TX-29 IT -продается в интернете недорогой ну и не самый дешёвый, самая маленькая цена была мною найдена в Чехии за 6 евро. Используемая частота: 868 Мгц Arduino UNIO BUONO R3 3,3V (или любая другая на 3,3 вольта) Приемопередатчик RTM12B 868 Мгц Схема подключения стандартная и взята на просторах интернета и рассчитана на подключение к ардуине с 3,3 вольта на борту , для избежания использования в схеме гасящих резисторов. Подключив все по схеме, незабывая антену Вид на макетке: Заливаем скетч из архива, в архиве 2 скетча: TX29IT-A - ловит все датчики в округе 100 метров и выводит в сериал информацию с датчиков в не декодированом HEX формате: 96 86 00 6A D0 где: // 9 = nibbles following // 68 = sensor id // 600 = temp // 6a = sensor type // d0 = crc Второй скетч TX29IT-B , более серьезный, с ним приемник ловит все датчики в округе 100 метров, но выводит в сериал уже удобоваримую информацию: |id| |°C |% | id:9C: 23.5:99 id:E8: -0.6:99 id:B8: 24.6:99 id:E8: -0.6:99 id:98: 36.6:99 id:E8: -0.6:99 ид устройства, температуру, и в перспективе влажность (используя другие датчики) и не забывает при этом еще помаргивать светодиодом на 9 ноге. Во 2 скетче режим отладки включается и выключается состоянием строки в заголовке: #define DEBUG 0 //отключена отладка или #define DEBUG 1 //включена отладка В архиве все необходимое для тестирования. Скетчи "собраны" в интернете, и написаны на языке CP (Сopy-Paste). Архив TX29IT.rar Последний раз редактировалось NEXT; 18.02.2014 в 02:38. |
|
|
|
![]() |
| Здесь присутствуют: 2 (пользователей: 0 , гостей: 2) | |
| Опции темы | Поиск в этой теме |
| Опции просмотра | |
|
|