Это повторяется одинаково с каждой посылкой? или по разному?
I и O - это уверенно определённые биты, но их мало и это явно конец посылки. Возможно сигнал слишком слабый, или очень много шума - АРУ отрабатывает очень медленно.
Возможно сильно шумит источник питания, если он импульсный... ПРобовали запитаться от батареи?
Простите меня за оффтоп, но я так долго мучался с получением данных от датчиков орегон, что когда случайно наткнулся на сайт Narodmon просто вздохнул. Да, понимаю, не мое, чужое, но какая разница, если датчики вон, в соседнем доме, да еще и с барометром :) Так что забил на свое, пользуюсь чужими данными.
Простите меня за оффтоп, но я так долго мучался с получением данных от датчиков орегон, что когда случайно наткнулся на сайт Narodmon просто вздохнул. Да, понимаю, не мое, чужое, но какая разница, если датчики вон, в соседнем доме, да еще и с барометром :) Так что забил на свое, пользуюсь чужими данными.
Неизвестно где висит датчик у соседа и что он показывает.
Свой надёжнее)) ИМХО
Простите меня за оффтоп, но я так долго мучался с получением данных от датчиков орегон, что когда случайно наткнулся на сайт Narodmon просто вздохнул. Да, понимаю, не мое, чужое, но какая разница, если датчики вон, в соседнем доме, да еще и с барометром :) Так что забил на свое, пользуюсь чужими данными.
Ну вообще-то, люди данные не из Великого Рандома берут, а часто с тех же погодных датчиков Oregon. А как собрать данные с них? - Правильно: Ардуино собирает и шлет на Narodmon.ru
Arduino: 1.6.11 (Windows 10), Плата:"Arduino/Genuino Uno"
C:\Users\Администратор\Documents\Arduino\UNORF-5V\UNORF-5V.ino: In function 'void loop()':
UNORF-5V:164: error: 'collect' was not declared in this scope
UNORF-5V:169: error: 'collect' was not declared in this scope
UNORF-5V:196: error: 'get_bits' was not declared in this scope
UNORF-5V:197: error: 'get_data' was not declared in this scope
UNORF-5V:223: error: 'get_data' was not declared in this scope
UNORF-5V:249: error: 'correlate_data' was not declared in this scope
UNORF-5V:261: error: 'assemble_data' was not declared in this scope
UNORF-5V:266: error: 'assemble_data' was not declared in this scope
UNORF-5V:288: error: 'get_info_data' was not declared in this scope
UNORF-5V:289: error: 'get_sensor' was not declared in this scope
UNORF-5V:290: error: 'restore_data' was not declared in this scope
UNORF-5V:291: error: 'check_CRC' was not declared in this scope
UNORF-5V:304: error: 'get_id' was not declared in this scope
UNORF-5V:306: error: 'get_channel' was not declared in this scope
UNORF-5V:315: error: 'get_battery' was not declared in this scope
UNORF-5V:319: error: 'get_temperature_mask' was not declared in this scope
UNORF-5V:320: error: 'get_temperature' was not declared in this scope
UNORF-5V:329: error: 'get_humidity_mask' was not declared in this scope
UNORF-5V:330: error: 'get_humidity' was not declared in this scope
exit status 1
'collect' was not declared in this scope
Этот отчёт будет иметь больше информации с
включенной опцией Файл -> Настройки ->
"Показать подробный вывод во время компиляции"
посмотрите код ошибки почему то.
и что значит #define MHZ 2 //Приёмник подключается к D2
Цифровой вход номер два!... ) Нумерация которых начинается с ноля. Получается третий от начала ) По поводу ошибки - скорее всего вы неправильно скопировали код с форума, надо через кнопку при наведении мышки на код "посмотреть скопировать код", а не из поста брать.
Цифровой вход номер два!... ) Нумерация которых начинается с ноля. Получается третий от начала ) По поводу ошибки - скорее всего вы неправильно скопировали код с форума, надо через кнопку при наведении мышки на код "посмотреть скопировать код", а не из поста брать.
PERIOD: 0 PACKET: 1D204510342043A43300 VALIDITY: FFFFFFFFFFFFFFFFFFFF TYPE: THGN132N
ID: 51 CHNL: 3 BAT: F TMP: 24.3C HUM: 34% CRC: OK PROC. TIME: 619ms
А в чём противоречие? В том, что я байты выдаю в том виде, в котором они приняты в описании протокола?
Да, в первом выдаваемом вами байте 1Ah младший полубайт "A" я не отношу к полученной посылке, т.к. считаю нибл синхронизации частью преамбулы. Он не несёт никакой информации...
посмотрите пожалуйста почему выше по теме выложил ошибку при компиляции. в чём может быть проблема
Такое впечатление, что у вас не весь код скопирован. Либо компилятор настроен так, что он не видит функцию, если она в коде вызывается раньше, чем описана. Можно попробовать поставить setup() и loop() в конце скетча
#define THGN132 0x1D20 //Типы известных датчиков
#define THN132 0xEC40
#define MHZ 2 //Приёмник подключается к D2
#define FIND_PACKET 1
#define ANALIZE_PACKETS 3
#define PER_LENGTH 976 // Период в мкс
#define THR_LENGTH 615 //Порог периода 0 или 1
#define LENGTH_TOLERANCE 20 //Допуск на период
#define READ_BITS 90 //Размер битовой посылки
#define READ_BITS2 180 //Двойной размер битовой посылки
#define PACKET_LENGTH 20 //Размер пакета данных
#define DEBUG_INFO 1 //Выводить ли диагностическую информацию
bool reciever_ctrl = true; //Флаг контроля ресивера (выставляется при приходе импулься, сбрасывается в таймере)
bool reciever_status = false; // Результат проверки состояния ресивера
//Массивы для хранения полученных данных:
float r_tmp[3]; //Температура
byte r_hmdty[3]; //Влажность. Если = 101 - значит нет данных
bool r_bat[3]; //Флаг батареи
bool r_isreceived[3]; //Флаг о том, что по данному каналу приходил хоть один правильный пакет
word r_type[3]; //Тип датчика
unsigned long rcv_time[3]; // времена прихода пакетов
byte _chnl;
byte receive_status, packet_number;
byte start_pulse_cnt;
unsigned long pulse_length, work_time, timer_marklong;
unsigned long pulse_marker, right_pulse_marker, last_premarker;
unsigned long pre_marker[4]; // Для хранения временных меток преамбулы ()
unsigned long first_packet_end;
bool crc_c; //Результат проверки CRC
word sens_type; //Тип сенсора
bool pulse_type; //Пустое
byte data_length, data_length2; //Длины пакетов
int data_val, data_val2; // Качество пакетов
//Массивы данных для записи данных с канала и полученных битов
byte collect_data[READ_BITS2], collect_data2[READ_BITS2];
//А когда становится массивом полученных битов, то значения такие:
// 0 - неизвестен
// >0 - единица
// <0 - ноль
byte decode_tacts[READ_BITS2]; //Массив тактов. значения
// 0=ноль
// 1=единица
// 2=неизвестен
// 3=переход+
// 4=переход-
///////// ПРЕРЫВАНИЕ ///////////////////////////////////////////////////////////////////////////////////////////
volatile unsigned long pm;
volatile unsigned long pl, timer_mark;
void int_0(void) {
if(digitalRead(MHZ)){
//Начало импульса
pl = 0;
pm = micros();
}
else{
//Конец импульса
//Вычисляется время окончания и длина
pl = micros() - pm;
pm += pl;
}
}
//////////////// УСТАНОВКИ ///////////////////////////////////////
void setup ()
{
Serial.begin(57600);
//Прерывание по сигналу от приёмника
pinMode(MHZ,INPUT);
attachInterrupt(0, int_0, CHANGE);
receive_status = FIND_PACKET;
start_pulse_cnt = 0;
packet_number = 0;
for (int i = 0; i < 3; i++){
rcv_time[i] = 7000000;
r_isreceived[i] = 0;
}
pinMode(13, OUTPUT); //Будем мигать светодиодом
digitalWrite(13, LOW);
}
//////////////// ГЛАВНЫЙ ЦИКЛ ///////////////////////////////////////
void loop()
{
noInterrupts();
pulse_length = pl;
pl = 0;
pulse_marker = pm;
interrupts();
//////////////////////////////////////////////////////////////////////
//Получен некий импульс,//////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
if (pulse_length != 0 && receive_status == FIND_PACKET){
reciever_ctrl = 1;
//Режим поиска пакета в эфире
if (start_pulse_cnt == 0){
//Найдена первый "правильный" импульс - длинная единица!
if (pulse_length < (PER_LENGTH) && pulse_length > (THR_LENGTH) ) {
start_pulse_cnt = 1;
pre_marker[start_pulse_cnt] = pulse_marker;
pulse_length = 0;
}
}
//Ищем следующие импульсы
else{
//Найден импуль правильной длины
if (pulse_length <= (PER_LENGTH) && pulse_length >= (THR_LENGTH)) {
//Если импульс в правильном месте, то добавляем счётчик найденых стартовых импульсов
if(pulse_marker - pre_marker[start_pulse_cnt] > (PER_LENGTH*2-LENGTH_TOLERANCE) && pulse_marker - pre_marker[start_pulse_cnt] < (PER_LENGTH * 2 + LENGTH_TOLERANCE)){
start_pulse_cnt++;
pre_marker[start_pulse_cnt] = pulse_marker;
pulse_length = 0;
}
///...если в неправильном месте то назначаем его первым
else{
start_pulse_cnt = 1;
pre_marker[start_pulse_cnt] = pulse_marker;
pulse_length = 0;
}
}
else{
//Если импульс неправильной длины, то стоит проверить, а не вышло ли время ожидания правильного импульса
if(pulse_marker - pre_marker[start_pulse_cnt] < (PER_LENGTH * 2 + LENGTH_TOLERANCE)){
//Время ещё не вышло, скорее всего это помеха. Пропускаем...
pulse_length = 0;
}
else{
//Время вышло, начинаем искать заново
start_pulse_cnt = 0;
pulse_length = 0;
}
}
}
}
if(packet_number == 1 && (millis() - first_packet_end) > 200){ // Если найден первый пакет и вышло вермя ожидания второго
// Не ждём второго, а переходм в режим анализа
receive_status = ANALIZE_PACKETS;
}
//////////////////////////////////////////////////////////////////////
// Сбор данных////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//Если Найдены три длинных единицы и два длинных нуля. Возможно это начало посылки...
if (start_pulse_cnt == 3 && receive_status == FIND_PACKET){
work_time = millis();
last_premarker = pre_marker[3];
start_pulse_cnt = 0;
if (packet_number == 0){
collect(collect_data, &data_length);
first_packet_end = millis();
packet_number = 1;
}
else{
collect(collect_data2, &data_length2);
packet_number = 2;
receive_status = ANALIZE_PACKETS;
}
}
if (receive_status == ANALIZE_PACKETS){
digitalWrite(13, HIGH);
//////////////////////////////////////////////////////////////////////
// Анализ данных////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
bool halfshift;
//Дамп собранных данных
/* if (DEBUG_INFO){
for(int bt = 0; bt < 180; bt++){
Serial.print(collect_data[bt], HEX);
Serial.print(' ');
}
Serial.println(" ");
for(int bt = 0; bt < 180; bt++){
Serial.print(collect_data2[bt],HEX);
Serial.print(' ');
}
Serial.println(" ");
}
*/
get_bits(collect_data);
if (get_data(0, collect_data) > get_data(1, collect_data)){
data_val = get_data(0, collect_data);
halfshift = 0;
}
else {
data_val = get_data(1, collect_data);
halfshift = 0;
}
if (DEBUG_INFO){
Serial.print("1) ");
for(int bt = 0; bt < READ_BITS; bt++){
if (collect_data[bt] > 128 + 1) Serial.print('I');
if (collect_data[bt] < 128 - 1) Serial.print('O');
if (collect_data[bt] == 128 + 1) Serial.print('i');
if (collect_data[bt] == 128 - 1) Serial.print('o');
if (collect_data[bt] == 128) Serial.print('.');
}
Serial.print(" VAL:");
Serial.print(data_val);
//Serial.print(" SIZE:");
//Serial.print(data_length);
Serial.print(" SHIFT:");
Serial.print(halfshift);
}
if (packet_number == 2){
get_bits(collect_data2);
if (get_data(0, collect_data2) > get_data(1, collect_data2)) {
data_val2 = get_data(0, collect_data2);
halfshift = 0;
}
else {
data_val2 = get_data(1, collect_data2);
halfshift = 1;
}
if (DEBUG_INFO){
Serial.println(" ");
Serial.print("2) ");
for(int bt = 0; bt < READ_BITS; bt++){
if (collect_data2[bt] > 128 + 1) Serial.print('I');
if (collect_data2[bt] < 128 - 1) Serial.print('O');
if (collect_data2[bt] == 128 + 1) Serial.print('i');
if (collect_data2[bt] == 128 - 1) Serial.print('o');
if (collect_data2[bt] == 128) Serial.print('.');
}
Serial.print(" VAL:");
Serial.print(data_val2);
//Serial.print(" SIZE:");
//Serial.print(data_length2);
Serial.print(" SHIFT:");
Serial.print(halfshift);
}
}
int correlation = correlate_data(collect_data, collect_data2);
if (DEBUG_INFO){
Serial.print(" COR: ");
Serial.println(correlation);
}
byte* result_data, result_data_start, aux_data;
if (packet_number == 1){
result_data = collect_data;
}
else{
if (correlation > 0){
result_data = collect_data2;
assemble_data(collect_data2,collect_data, &correlation);
}
else{
result_data = collect_data;
correlation = -correlation;
assemble_data(collect_data, collect_data2, &correlation);
}
//Вывод готовой посылки
}
if (DEBUG_INFO){
Serial.print("RESULT ");
byte* rdt = result_data;
for(int bt = 0; bt < READ_BITS; bt++){
if (*rdt > 128 + 1) Serial.print('I');
if (*rdt < 128 - 1) Serial.print('O');
if (*rdt == 128 + 1) Serial.print('i');
if (*rdt == 128 - 1) Serial.print('o');
if (*rdt == 128) Serial.print('.');
rdt++;
}
Serial.println(" ");
}
//Обработка посылки
Serial.print("PERIOD: ");
Serial.print(millis()/40000);
Serial.print(" ");
byte packet[PACKET_LENGTH], valid_p[PACKET_LENGTH];
if (get_info_data(result_data, packet, valid_p)){
sens_type = get_sensor(packet); //Определяем тип пакета по типу датчика
restore_data(packet, sens_type); // Восстанавливаем данные по типу датчика
crc_c = check_CRC(packet, sens_type); // Проверяем CRC, если оно верно, то все сомнительные биты делаем уверенными
if (crc_c) for (byte www = 0; www < PACKET_LENGTH; www++) valid_p[www] = 0x0f;
Serial.print(" PACKET: ");
for (int q = 0;q < PACKET_LENGTH; q++) Serial.print(packet[q], HEX);
Serial.print(" VALIDITY: ");
for (int q = 0; q < PACKET_LENGTH; q++) Serial.print(valid_p[q], HEX);
}
if (sens_type == THGN132 || sens_type == THN132){
Serial.print(" TYPE: ");
if (sens_type == THGN132) Serial.print("THGN132N ");
if (sens_type == THN132) Serial.print("THN132N ");
Serial.print("ID: ");
Serial.print(get_id(packet), HEX);
Serial.print(" CHNL: ");
_chnl=get_channel(packet)-1;
Serial.print(_chnl+1);
r_type[_chnl] = sens_type;
if (crc_c) r_isreceived[_chnl] = 1;
//......Если получен правильный пакет, сбрасываем таймер
if(crc_c) rcv_time[_chnl] = millis(); //
Serial.print(" BAT: ");
if(crc_c) r_bat[_chnl] = get_battery(packet);
if (r_bat[_chnl]) Serial.print("F "); else Serial.print("e ");
Serial.print("TMP: ");
if(get_temperature_mask(valid_p)){
if(crc_c) r_tmp[_chnl] = get_temperature(packet);
Serial.print(r_tmp[_chnl], 1);
}
else {
Serial.print("----");
}
Serial.print("C ");
if (sens_type == THGN132) {
Serial.print("HUM: ");
if (get_humidity_mask(valid_p)) {
if(crc_c) r_hmdty[_chnl] = get_humidity(packet);
Serial.print(r_hmdty[_chnl], 1);
}
else{
Serial.print("--");
r_hmdty[_chnl] = 101;
}
Serial.print("%");
}
else Serial.print(" ");
Serial.print(" CRC: ");
if (crc_c) Serial.print("OK ");
else Serial.print("-- ");
Serial.print(" PROC. TIME: ");
Serial.print(millis() - work_time);
Serial.println("ms ");
}
else Serial.println(" WRONG ");
// Возвращаемся к исходному состоянию
receive_status = FIND_PACKET;
packet_number = 0;
start_pulse_cnt = 0;
sens_type = 0;
_chnl = 0;
digitalWrite(13, LOW);
}
//////////////////////////////////////////////////////////////////////
//Здесь записываются остальные процедуры, например те, которые выполняются ежесекундно
//////////////////////////////////////////////////////////////////////
if ((millis() - timer_mark) > 1000) {
{
if (!reciever_status) Serial.println("RECEIVING...");
reciever_status = 1;
}
reciever_ctrl = 0;
}
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//Извлекает из тактовой последовательности - битовую
//Параметры: cdptr - указатель на записанную тактовую последовательность
////////////////////////////////////////////////////////////////////////////////////////////////////
void get_bits(byte* cdptr){
//Сброс массивов
byte* cdp=cdptr;
for(int bt=0 ; bt<READ_BITS*2; bt++) decode_tacts[bt]=2;
for(int bt=0 ; bt<READ_BITS*2; bt++){
if ((*cdp&0xf0)>0x20 && (*cdp&0x0f)>0x04) decode_tacts[bt]=1;
if ((*cdp&0xf0)<0x30 && (*cdp&0x0f)<0x05) decode_tacts[bt]=0;
if ((*cdp&0xf0)<0x20 && (*cdp&0x0f)>0x04) decode_tacts[bt]=4;
if ((*cdp&0xf0)>0x40 && (*cdp&0x0f)<0x02) decode_tacts[bt]=3;
*cdp++;
}
return;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//Извлекает из записи канала тактовую последовательность
//Параметры: cdptr - указатель на записанные данные
// btt - смещение в тактах. Смещение на такт при анализе может поммочь восстановить пакет, у которого разрушено начало
// Функция вовзращает качество или "годность" расшифровки - количесвто уверенно узнаных тактов.
// Сравнивая годность с btt=0 и btt=1 выбираем лучшую
////////////////////////////////////////////////////////////////////////////////////////////////////
int get_data(int btt, byte* cdptr){ //btt - смещение на такт при анализе может поммочь восстановить пакет, у которого разрушено начало
byte* cdp=cdptr;
for(int bt=0 ; bt<READ_BITS; bt++){
*cdp=128;
cdp++;
}
cdp=cdptr;
*cdp=(128+2);
cdp++;
int packet_validity=0;
for(int bt=1 ; bt<READ_BITS; bt++){
if(decode_tacts[bt*2-btt]==0) *cdp-=1;
if(decode_tacts[bt*2-btt]==1) *cdp+=1;
if(decode_tacts[bt*2-2-btt]==1 && decode_tacts[bt*2-1-btt]==4) *cdp-=1;
if(decode_tacts[bt*2-2-btt]==0 && decode_tacts[bt*2-1-btt]==3) *cdp+=1;
if(decode_tacts[bt*2-2-btt]==0 && decode_tacts[bt*2-1-btt]==1) *cdp-=1;
if(decode_tacts[bt*2-2-btt]==1 && decode_tacts[bt*2-1-btt]==0) *cdp+=1;
if(decode_tacts[bt*2+2-btt]==1 && decode_tacts[bt*2+1-btt]==3) *cdp-=1;
if(decode_tacts[bt*2+2-btt]==0 && decode_tacts[bt*2+1-btt]==4) *cdp+=1;
if(decode_tacts[bt*2+2-btt]==0 && decode_tacts[bt*2+1-btt]==1) *cdp-=1;
if(decode_tacts[bt*2+2-btt]==1 && decode_tacts[bt*2+1-btt]==0) *cdp+=1;
//Подсчитываем кол-во достоверных бит в пакете
if (*cdp>(128+1) ) packet_validity+=*cdp-128;
if (*cdp<(128-1)) packet_validity+=128-*cdp;
cdp++;
}
return packet_validity;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//Прослушивание канала с частотой дискретизации 16384Гц
////////////////////////////////////////////////////////////////////////////////////////////////////
void collect(byte* cdptr, byte* dtl){
// В функцию передаётся уазатель на область памяти, куда сливать данные.
*dtl=0;
bool cdp_prev_null;
byte* cdp=cdptr;
byte nulls_found=0;
unsigned long tmp_marker=last_premarker+PER_LENGTH/32; //
byte bt2=0;
*cdp=0x88; //Первые два такта - единицы. Мы же поймали импульс!
cdp++;
//Ждём момента наступления первого считывания (конец последнего импулься зацепки + 1/16 такта)
while (micros() <= tmp_marker);
//Начинаем читать данные в память!
for(int bt=1 ; bt<READ_BITS*2; bt++){// чИТАЕМ максимум ПО 90 БИТ (ПОСЫЛКА thgn - 96БИТ, THN - 76 бИТ + как минимум 3 бита 111, которые мы уже нашли)
*cdp=0;
for(byte ckl=0; ckl<8; ckl++){ // Читаем 8 раз за полутакт
if (digitalRead(MHZ)) *cdp+=0x10; // Измерения запиываем в старший полубайт
tmp_marker+=PER_LENGTH/16;
while (micros() < tmp_marker);
}
last_premarker+=PER_LENGTH/2;
tmp_marker=last_premarker+PER_LENGTH/32;
for(byte ckl=0; ckl<8; ckl++){
if (digitalRead(MHZ)) *cdp+=1; // В следующий полутакт измерения запиываем в младший полубайт. Это экономит память.
tmp_marker+=PER_LENGTH/16;
while (micros() < tmp_marker);
}
last_premarker+=PER_LENGTH/2;
bt2++;
// Каждые 8 тактов добавлять 5мкс для выравнивания периода с 976мкс до 976.56мкс
if (bt2==8){
last_premarker+=5;
bt2=0;
}
tmp_marker=last_premarker+PER_LENGTH/32;
while (micros() < last_premarker);//Ждём прихода времени следующего полутакта
if (*cdp==0 && cdp_prev_null==1) nulls_found++;
//if (*cdp==0 && (*(cdp-1)==0)) nulls_found++;
else nulls_found=0;
if (nulls_found>1) return; //Если найдено более 7 нулевых тактов подряд, значит либо жёсткая помеха, убившая пакет
//Либо конец посылки. Дальше читать нет смысла.
cdp_prev_null= (*cdp==0) ? 1 : 0;
cdp++;
*dtl+=1;
}
return;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//Определение смещения пакетов друг относительно друга
//В качестве параметров передаются указатели на массивы данных
// Возваращаяется смещение
// >0 - второй пакет начался раньше, <0 - Первый пакет начался раньше
////////////////////////////////////////////////////////////////////////////////////////////////////
int correlate_data(byte* ser1, byte* ser2){
byte best_correl=0;
int best_shift=0;
byte best_correl_back=0;
int best_shift_back=0;
byte shift_score[READ_BITS];
byte* s1;
byte* s2;
byte* s2t=ser2;
//смещаем первый пакет относительно второго
for( byte sht=0; sht<READ_BITS; sht++){
s1=ser1;
s2=s2t;
shift_score[sht]=0;
for(byte sp=0; sp<READ_BITS-sht; sp++){
if ((*s1 >(128+1) && *s2 >(128+1))||(*s1 <(128-1) && *s2 <(128-1)) ) shift_score[sht]++;
s2++;
s1++;
}
s2t++;
}
for (int i=0; i<READ_BITS; i++){
if (shift_score[i]>best_correl){
best_correl=shift_score[i];
best_shift=i;
}
}
//Теперь наоборот -втрой пакет относительно первого
byte* s1t=ser1;
for( byte sht=0; sht<READ_BITS; sht++){
s2=ser2;
s1=s1t;
shift_score[sht]=0;
for(byte sp=0; sp<READ_BITS-sht; sp++){
if ((*s1 >(128+1) && *s2 >(128+1))||(*s1 <(128-1) && *s2 <(128-1)) ) shift_score[sht]++;
s2++;
s1++;
}
s1t++;
}
// Ищем наилучшее совпадение для обоих вариантов
for (int i=0; i<READ_BITS; i++){
if (shift_score[i]>best_correl_back){
best_correl_back=shift_score[i];
best_shift_back=i;
}
}
//И возвращаем самое лучшее из двух
if (best_correl_back > best_correl) return -best_shift_back;
else return best_shift;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//Сборка из двух пакетов
//В качестве параметров передаются указатели на массивы данных
// Причём первым должен идти результирующий пакет, т.е. тот который имеет более длинную преамбулу.
//shift - смещение втрого пакета относительного первого
////////////////////////////////////////////////////////////////////////////////////////////////////
void assemble_data(byte* s1, byte* s2, int* shift){
for (int g=0; g<=*shift-1; g++) s1++;
for (int i=0; i<(READ_BITS-*shift); i++){
if(*s1 < (128+2) && *s1 > (128-2) && (*s2>(128+1) || *s2<(128-1))) {
*s1=*s2;
}
s1++;
s2++;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//Создаёт кодовую посылку
//code - указатель на расшифрованную битовую последовательность
//result - указатель на кодовую посылку
//valid - указатель на карту достоверности кодовой посылки
////////////////////////////////////////////////////////////////////////////////////////////////////
byte get_info_data(byte* code, byte* result, byte* valid){
byte* rd=result;
byte* vd=valid;
//Чистим массивы
for (int l=0; l<PACKET_LENGTH; l++){
*vd=0;
*rd=0;
vd++;
rd++;
}
int csm;
for (csm=0; csm<30;csm++){
if (*code<128 && *(code+1)>128 && *(code+2)<128 && *(code+3)>128) break;//Найдена последовательность 0101
code++;
}
if (csm>22) return 0;// Стартовая последовательность в первых 20 битах не найдена, такой пакет этим методом не расшифруешь
code+=4;//Переходим на начало считывания
int ii=0;
for (int i=0; i<READ_BITS-csm; i++)
{
byte multipl;
switch (ii){
case 0: {multipl=0x01; break;}
case 1: {multipl=0x02; break;}
case 2: {multipl=0x04; break;}
case 3: {multipl=0x08; break;}
}
if (*code==129 ) *result+=multipl;
if (*code>129 ) {
*result+=multipl;
*valid+=multipl;
}
if (*code<127 ) *valid+=multipl;
code++;
ii++;
if (ii==4) {
ii=0;
valid++;
result++;
}
}
return 1;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//Возвращает значение температуры
//oregon_data - указатель на кодовую посылку
////////////////////////////////////////////////////////////////////////////////////////////////////
float get_temperature(byte* oregon_data){
float tmprt;
oregon_data+=8;
//исправляем возможные ошибки:
for (int g=0;g<4; g++) if (*(oregon_data+g)>9) *(oregon_data+g)=*(oregon_data+g)-8;
tmprt+=*(oregon_data)*0.1;
tmprt+=*(oregon_data+1);
tmprt+=*(oregon_data+2)*10;
return (*(oregon_data+3)) ? -tmprt : tmprt;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//Возвращает значение маски годности
//validity_data - указатель на карту достоверности кодовой посылки
////////////////////////////////////////////////////////////////////////////////////////////////////
byte get_temperature_mask(byte* validity_data){
return (*(validity_data+8)==0x0f && *(validity_data+9)==0x0f && *(validity_data+10)==0x0f && *(validity_data+11)==0x0f) ? 1 : 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//Возвращает тип сенсора
//oregon_data - указатель на кодовую посылку
////////////////////////////////////////////////////////////////////////////////////////////////////
word get_sensor(byte* oregon_data){
return (word)(*(oregon_data))*0x1000 + (*(oregon_data+1))*0x0100 + (*(oregon_data+2))*0x10 + *(oregon_data+3);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//Возвращает значение канала
//oregon_data - указатель на кодовую посылку
////////////////////////////////////////////////////////////////////////////////////////////////////
byte get_channel(byte* oregon_data){
byte channel;
switch (*(oregon_data+4))
{
case 1:
channel = 1;
break;
case 2:
channel = 2;
break;
case 4:
channel = 3;
break;
}
return channel;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
byte get_battery(byte* oregon_data){
return (*(oregon_data+7) & 0x4) ? 0 : 1;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//Возвращает значение влажности
//oregon_data - указатель на кодовую посылку
////////////////////////////////////////////////////////////////////////////////////////////////////
byte get_humidity(byte* oregon_data){
byte tmprt;
oregon_data+=12;
//исправляем возможные ошибки:
for (int g=0;g<2; g++) if (*(oregon_data+g)>9) *(oregon_data+g)=*(oregon_data+g)-8;
tmprt=*(oregon_data);
tmprt+=*(oregon_data+1)*10;
return tmprt;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//Возвращает значение маски годности влажности 4 бита, старший - знак, младший - десятые доли градуса
//validity_data - указатель на карту достоверности кодовой посылки
////////////////////////////////////////////////////////////////////////////////////////////////////
byte get_humidity_mask(byte* validity_data){
return (*(validity_data+13)==0x0f && *(validity_data+14)==0x0f) ? 1 : 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//Возвращает id датчика
//oregon_data - указатель на кодовую посылку
////////////////////////////////////////////////////////////////////////////////////////////////////
byte get_id(byte* oregon_data){
byte tmprt;
oregon_data+=5;
tmprt=*(oregon_data)*0x10;
tmprt+=*(oregon_data+1);
return tmprt;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//Проверка CRC
//oregon_data - указатель на кодовую посылку
////////////////////////////////////////////////////////////////////////////////////////////////////
bool check_CRC(byte* oregon_data, word sensor_type){
byte* pp=oregon_data;
byte crc, resived_crc;
crc=0;
if (sensor_type==THGN132){
for(int x=0; x<15; x++){
crc+=*pp;
pp++;
}
resived_crc=(*(oregon_data+15))+(*(oregon_data+16))*0x10;
return (resived_crc==crc)? 1 : 0;
}
if (sensor_type==THN132){
for(int x=0; x<12; x++){
crc+=*pp;
pp++;
}
resived_crc=(*(oregon_data+12))+(*(oregon_data+13))*0x10;
return (resived_crc==crc)? 1 : 0;
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//Востановление данных по типу датчика
////////////////////////////////////////////////////////////////////////////////////////////////////
void restore_data(byte* oregon_data, word sensor_type){
byte* pp=oregon_data;
if (sensor_type==THGN132){
pp+=8;
for(int x=0; x<6; x++){
if(*pp>9 && x!=3) *pp-=8;
pp++;
}
}
if (sensor_type==THN132){
pp+=8;
for(int x=0; x<3; x++){
if(*pp>9) *pp-=8;
pp++;
}
}
return;
}
скопировал ваш код, попытался скомпилировать. выдало ошибку. выделил весь код и поместил сюда. можно поправить код чтобы собралась прошивка. я слабоват в написании
В ряде случаев компилятор Си может плеваться, если в тексте функция описывается по тексту ниже места её первого вызова. Мы проблему решили переместив тело функции выше её вызова. Хотя грамотнее было бы использовать прототипы функций. Подробнее можно вот тут, например, почитать:
посмотрите пожалуйста почему выше по теме выложил ошибку при компиляции. в чём может быть проблема
Автор в предыдущем посте вам правильно ответил - нужно использовать прототипы. Но если вы не хотите морочиться просто перенисите функции setup() и loop() в самый конец кода.
Вот так:
#define THGN132 0x1D20 //Типы известных датчиков
#define THN132 0xEC40
#define MHZ 2 //Приёмник подключается к D2
#define FIND_PACKET 1
#define ANALIZE_PACKETS 3
#define PER_LENGTH 976 // Период в мкс
#define THR_LENGTH 615 //Порог периода 0 или 1
#define LENGTH_TOLERANCE 20 //Допуск на период
#define READ_BITS 90 //Размер битовой посылки
#define READ_BITS2 180 //Двойной размер битовой посылки
#define PACKET_LENGTH 20 //Размер пакета данных
#define DEBUG_INFO 1 //Выводить ли диагностическую информацию
bool reciever_ctrl = true; //Флаг контроля ресивера (выставляется при приходе импулься, сбрасывается в таймере)
bool reciever_status = false; // Результат проверки состояния ресивера
//Массивы для хранения полученных данных:
float r_tmp[3]; //Температура
byte r_hmdty[3]; //Влажность. Если = 101 - значит нет данных
bool r_bat[3]; //Флаг батареи
bool r_isreceived[3]; //Флаг о том, что по данному каналу приходил хоть один правильный пакет
word r_type[3]; //Тип датчика
unsigned long rcv_time[3]; // времена прихода пакетов
byte _chnl;
byte receive_status, packet_number;
byte start_pulse_cnt;
unsigned long pulse_length, work_time, timer_marklong;
unsigned long pulse_marker, right_pulse_marker, last_premarker;
unsigned long pre_marker[4]; // Для хранения временных меток преамбулы ()
unsigned long first_packet_end;
bool crc_c; //Результат проверки CRC
word sens_type; //Тип сенсора
bool pulse_type; //Пустое
byte data_length, data_length2; //Длины пакетов
int data_val, data_val2; // Качество пакетов
//Массивы данных для записи данных с канала и полученных битов
byte collect_data[READ_BITS2], collect_data2[READ_BITS2];
//А когда становится массивом полученных битов, то значения такие:
// 0 - неизвестен
// >0 - единица
// <0 - ноль
byte decode_tacts[READ_BITS2]; //Массив тактов. значения
// 0=ноль
// 1=единица
// 2=неизвестен
// 3=переход+
// 4=переход-
///////// ПРЕРЫВАНИЕ ///////////////////////////////////////////////////////////////////////////////////////////
volatile unsigned long pm;
volatile unsigned long pl, timer_mark;
void int_0(void) {
if (digitalRead(MHZ)) {
//Начало импульса
pl = 0;
pm = micros();
}
else {
//Конец импульса
//Вычисляется время окончания и длина
pl = micros() - pm;
pm += pl;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//Извлекает из тактовой последовательности - битовую
//Параметры: cdptr - указатель на записанную тактовую последовательность
////////////////////////////////////////////////////////////////////////////////////////////////////
void get_bits(byte* cdptr) {
//Сброс массивов
byte* cdp = cdptr;
for (int bt = 0; bt<READ_BITS * 2; bt++) decode_tacts[bt] = 2;
for (int bt = 0; bt<READ_BITS * 2; bt++) {
if ((*cdp & 0xf0)>0x20 && (*cdp & 0x0f)>0x04) decode_tacts[bt] = 1;
if ((*cdp & 0xf0)<0x30 && (*cdp & 0x0f)<0x05) decode_tacts[bt] = 0;
if ((*cdp & 0xf0)<0x20 && (*cdp & 0x0f)>0x04) decode_tacts[bt] = 4;
if ((*cdp & 0xf0)>0x40 && (*cdp & 0x0f)<0x02) decode_tacts[bt] = 3;
*cdp++;
}
return;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//Извлекает из записи канала тактовую последовательность
//Параметры: cdptr - указатель на записанные данные
// btt - смещение в тактах. Смещение на такт при анализе может поммочь восстановить пакет, у которого разрушено начало
// Функция вовзращает качество или "годность" расшифровки - количесвто уверенно узнаных тактов.
// Сравнивая годность с btt=0 и btt=1 выбираем лучшую
////////////////////////////////////////////////////////////////////////////////////////////////////
int get_data(int btt, byte* cdptr) { //btt - смещение на такт при анализе может поммочь восстановить пакет, у которого разрушено начало
byte* cdp = cdptr;
for (int bt = 0; bt<READ_BITS; bt++) {
*cdp = 128;
cdp++;
}
cdp = cdptr;
*cdp = (128 + 2);
cdp++;
int packet_validity = 0;
for (int bt = 1; bt<READ_BITS; bt++) {
if (decode_tacts[bt * 2 - btt] == 0) *cdp -= 1;
if (decode_tacts[bt * 2 - btt] == 1) *cdp += 1;
if (decode_tacts[bt * 2 - 2 - btt] == 1 && decode_tacts[bt * 2 - 1 - btt] == 4) *cdp -= 1;
if (decode_tacts[bt * 2 - 2 - btt] == 0 && decode_tacts[bt * 2 - 1 - btt] == 3) *cdp += 1;
if (decode_tacts[bt * 2 - 2 - btt] == 0 && decode_tacts[bt * 2 - 1 - btt] == 1) *cdp -= 1;
if (decode_tacts[bt * 2 - 2 - btt] == 1 && decode_tacts[bt * 2 - 1 - btt] == 0) *cdp += 1;
if (decode_tacts[bt * 2 + 2 - btt] == 1 && decode_tacts[bt * 2 + 1 - btt] == 3) *cdp -= 1;
if (decode_tacts[bt * 2 + 2 - btt] == 0 && decode_tacts[bt * 2 + 1 - btt] == 4) *cdp += 1;
if (decode_tacts[bt * 2 + 2 - btt] == 0 && decode_tacts[bt * 2 + 1 - btt] == 1) *cdp -= 1;
if (decode_tacts[bt * 2 + 2 - btt] == 1 && decode_tacts[bt * 2 + 1 - btt] == 0) *cdp += 1;
//Подсчитываем кол-во достоверных бит в пакете
if (*cdp>(128 + 1)) packet_validity += *cdp - 128;
if (*cdp<(128 - 1)) packet_validity += 128 - *cdp;
cdp++;
}
return packet_validity;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//Прослушивание канала с частотой дискретизации 16384Гц
////////////////////////////////////////////////////////////////////////////////////////////////////
void collect(byte* cdptr, byte* dtl) {
// В функцию передаётся уазатель на область памяти, куда сливать данные.
*dtl = 0;
bool cdp_prev_null;
byte* cdp = cdptr;
byte nulls_found = 0;
unsigned long tmp_marker = last_premarker + PER_LENGTH / 32; //
byte bt2 = 0;
*cdp = 0x88; //Первые два такта - единицы. Мы же поймали импульс!
cdp++;
//Ждём момента наступления первого считывания (конец последнего импулься зацепки + 1/16 такта)
while (micros() <= tmp_marker);
//Начинаем читать данные в память!
for (int bt = 1; bt<READ_BITS * 2; bt++) {// чИТАЕМ максимум ПО 90 БИТ (ПОСЫЛКА thgn - 96БИТ, THN - 76 бИТ + как минимум 3 бита 111, которые мы уже нашли)
*cdp = 0;
for (byte ckl = 0; ckl<8; ckl++) { // Читаем 8 раз за полутакт
if (digitalRead(MHZ)) *cdp += 0x10; // Измерения запиываем в старший полубайт
tmp_marker += PER_LENGTH / 16;
while (micros() < tmp_marker);
}
last_premarker += PER_LENGTH / 2;
tmp_marker = last_premarker + PER_LENGTH / 32;
for (byte ckl = 0; ckl<8; ckl++) {
if (digitalRead(MHZ)) *cdp += 1; // В следующий полутакт измерения запиываем в младший полубайт. Это экономит память.
tmp_marker += PER_LENGTH / 16;
while (micros() < tmp_marker);
}
last_premarker += PER_LENGTH / 2;
bt2++;
// Каждые 8 тактов добавлять 5мкс для выравнивания периода с 976мкс до 976.56мкс
if (bt2 == 8) {
last_premarker += 5;
bt2 = 0;
}
tmp_marker = last_premarker + PER_LENGTH / 32;
while (micros() < last_premarker);//Ждём прихода времени следующего полутакта
if (*cdp == 0 && cdp_prev_null == 1) nulls_found++;
//if (*cdp==0 && (*(cdp-1)==0)) nulls_found++;
else nulls_found = 0;
if (nulls_found>1) return; //Если найдено более 7 нулевых тактов подряд, значит либо жёсткая помеха, убившая пакет
//Либо конец посылки. Дальше читать нет смысла.
cdp_prev_null = (*cdp == 0) ? 1 : 0;
cdp++;
*dtl += 1;
}
return;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//Определение смещения пакетов друг относительно друга
//В качестве параметров передаются указатели на массивы данных
// Возваращаяется смещение
// >0 - второй пакет начался раньше, <0 - Первый пакет начался раньше
////////////////////////////////////////////////////////////////////////////////////////////////////
int correlate_data(byte* ser1, byte* ser2) {
byte best_correl = 0;
int best_shift = 0;
byte best_correl_back = 0;
int best_shift_back = 0;
byte shift_score[READ_BITS];
byte* s1;
byte* s2;
byte* s2t = ser2;
//смещаем первый пакет относительно второго
for (byte sht = 0; sht<READ_BITS; sht++) {
s1 = ser1;
s2 = s2t;
shift_score[sht] = 0;
for (byte sp = 0; sp<READ_BITS - sht; sp++) {
if ((*s1 >(128 + 1) && *s2 >(128 + 1)) || (*s1 <(128 - 1) && *s2 <(128 - 1))) shift_score[sht]++;
s2++;
s1++;
}
s2t++;
}
for (int i = 0; i<READ_BITS; i++) {
if (shift_score[i]>best_correl) {
best_correl = shift_score[i];
best_shift = i;
}
}
//Теперь наоборот -втрой пакет относительно первого
byte* s1t = ser1;
for (byte sht = 0; sht<READ_BITS; sht++) {
s2 = ser2;
s1 = s1t;
shift_score[sht] = 0;
for (byte sp = 0; sp<READ_BITS - sht; sp++) {
if ((*s1 >(128 + 1) && *s2 >(128 + 1)) || (*s1 <(128 - 1) && *s2 <(128 - 1))) shift_score[sht]++;
s2++;
s1++;
}
s1t++;
}
// Ищем наилучшее совпадение для обоих вариантов
for (int i = 0; i<READ_BITS; i++) {
if (shift_score[i]>best_correl_back) {
best_correl_back = shift_score[i];
best_shift_back = i;
}
}
//И возвращаем самое лучшее из двух
if (best_correl_back > best_correl) return -best_shift_back;
else return best_shift;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//Сборка из двух пакетов
//В качестве параметров передаются указатели на массивы данных
// Причём первым должен идти результирующий пакет, т.е. тот который имеет более длинную преамбулу.
//shift - смещение втрого пакета относительного первого
////////////////////////////////////////////////////////////////////////////////////////////////////
void assemble_data(byte* s1, byte* s2, int* shift) {
for (int g = 0; g <= *shift - 1; g++) s1++;
for (int i = 0; i<(READ_BITS - *shift); i++) {
if (*s1 < (128 + 2) && *s1 >(128 - 2) && (*s2>(128 + 1) || *s2<(128 - 1))) {
*s1 = *s2;
}
s1++;
s2++;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//Создаёт кодовую посылку
//code - указатель на расшифрованную битовую последовательность
//result - указатель на кодовую посылку
//valid - указатель на карту достоверности кодовой посылки
////////////////////////////////////////////////////////////////////////////////////////////////////
byte get_info_data(byte* code, byte* result, byte* valid) {
byte* rd = result;
byte* vd = valid;
//Чистим массивы
for (int l = 0; l<PACKET_LENGTH; l++) {
*vd = 0;
*rd = 0;
vd++;
rd++;
}
int csm;
for (csm = 0; csm<30; csm++) {
if (*code<128 && *(code + 1)>128 && *(code + 2)<128 && *(code + 3)>128) break;//Найдена последовательность 0101
code++;
}
if (csm>22) return 0;// Стартовая последовательность в первых 20 битах не найдена, такой пакет этим методом не расшифруешь
code += 4;//Переходим на начало считывания
int ii = 0;
for (int i = 0; i<READ_BITS - csm; i++)
{
byte multipl;
switch (ii) {
case 0: {multipl = 0x01; break; }
case 1: {multipl = 0x02; break; }
case 2: {multipl = 0x04; break; }
case 3: {multipl = 0x08; break; }
}
if (*code == 129) *result += multipl;
if (*code>129) {
*result += multipl;
*valid += multipl;
}
if (*code<127) *valid += multipl;
code++;
ii++;
if (ii == 4) {
ii = 0;
valid++;
result++;
}
}
return 1;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//Возвращает значение температуры
//oregon_data - указатель на кодовую посылку
////////////////////////////////////////////////////////////////////////////////////////////////////
float get_temperature(byte* oregon_data) {
float tmprt;
oregon_data += 8;
//исправляем возможные ошибки:
for (int g = 0; g<4; g++) if (*(oregon_data + g)>9) *(oregon_data + g) = *(oregon_data + g) - 8;
tmprt += *(oregon_data)*0.1;
tmprt += *(oregon_data + 1);
tmprt += *(oregon_data + 2) * 10;
return (*(oregon_data + 3)) ? -tmprt : tmprt;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//Возвращает значение маски годности
//validity_data - указатель на карту достоверности кодовой посылки
////////////////////////////////////////////////////////////////////////////////////////////////////
byte get_temperature_mask(byte* validity_data) {
return (*(validity_data + 8) == 0x0f && *(validity_data + 9) == 0x0f && *(validity_data + 10) == 0x0f && *(validity_data + 11) == 0x0f) ? 1 : 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//Возвращает тип сенсора
//oregon_data - указатель на кодовую посылку
////////////////////////////////////////////////////////////////////////////////////////////////////
word get_sensor(byte* oregon_data) {
return (word)(*(oregon_data)) * 0x1000 + (*(oregon_data + 1)) * 0x0100 + (*(oregon_data + 2)) * 0x10 + *(oregon_data + 3);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//Возвращает значение канала
//oregon_data - указатель на кодовую посылку
////////////////////////////////////////////////////////////////////////////////////////////////////
byte get_channel(byte* oregon_data) {
byte channel;
switch (*(oregon_data + 4))
{
case 1:
channel = 1;
break;
case 2:
channel = 2;
break;
case 4:
channel = 3;
break;
}
return channel;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
byte get_battery(byte* oregon_data) {
return (*(oregon_data + 7) & 0x4) ? 0 : 1;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//Возвращает значение влажности
//oregon_data - указатель на кодовую посылку
////////////////////////////////////////////////////////////////////////////////////////////////////
byte get_humidity(byte* oregon_data) {
byte tmprt;
oregon_data += 12;
//исправляем возможные ошибки:
for (int g = 0; g<2; g++) if (*(oregon_data + g)>9) *(oregon_data + g) = *(oregon_data + g) - 8;
tmprt = *(oregon_data);
tmprt += *(oregon_data + 1) * 10;
return tmprt;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//Возвращает значение маски годности влажности 4 бита, старший - знак, младший - десятые доли градуса
//validity_data - указатель на карту достоверности кодовой посылки
////////////////////////////////////////////////////////////////////////////////////////////////////
byte get_humidity_mask(byte* validity_data) {
return (*(validity_data + 13) == 0x0f && *(validity_data + 14) == 0x0f) ? 1 : 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//Возвращает id датчика
//oregon_data - указатель на кодовую посылку
////////////////////////////////////////////////////////////////////////////////////////////////////
byte get_id(byte* oregon_data) {
byte tmprt;
oregon_data += 5;
tmprt = *(oregon_data) * 0x10;
tmprt += *(oregon_data + 1);
return tmprt;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//Проверка CRC
//oregon_data - указатель на кодовую посылку
////////////////////////////////////////////////////////////////////////////////////////////////////
bool check_CRC(byte* oregon_data, word sensor_type) {
byte* pp = oregon_data;
byte crc, resived_crc;
crc = 0;
if (sensor_type == THGN132) {
for (int x = 0; x<15; x++) {
crc += *pp;
pp++;
}
resived_crc = (*(oregon_data + 15)) + (*(oregon_data + 16)) * 0x10;
return (resived_crc == crc) ? 1 : 0;
}
if (sensor_type == THN132) {
for (int x = 0; x<12; x++) {
crc += *pp;
pp++;
}
resived_crc = (*(oregon_data + 12)) + (*(oregon_data + 13)) * 0x10;
return (resived_crc == crc) ? 1 : 0;
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//Востановление данных по типу датчика
////////////////////////////////////////////////////////////////////////////////////////////////////
void restore_data(byte* oregon_data, word sensor_type) {
byte* pp = oregon_data;
if (sensor_type == THGN132) {
pp += 8;
for (int x = 0; x<6; x++) {
if (*pp>9 && x != 3) *pp -= 8;
pp++;
}
}
if (sensor_type == THN132) {
pp += 8;
for (int x = 0; x<3; x++) {
if (*pp>9) *pp -= 8;
pp++;
}
}
return;
}
//////////////// УСТАНОВКИ ///////////////////////////////////////
void setup()
{
Serial.begin(57600);
//Прерывание по сигналу от приёмника
pinMode(MHZ, INPUT);
attachInterrupt(0, int_0, CHANGE);
receive_status = FIND_PACKET;
start_pulse_cnt = 0;
packet_number = 0;
for (int i = 0; i < 3; i++) {
rcv_time[i] = 7000000;
r_isreceived[i] = 0;
}
pinMode(13, OUTPUT); //Будем мигать светодиодом
digitalWrite(13, LOW);
}
//////////////// ГЛАВНЫЙ ЦИКЛ ///////////////////////////////////////
void loop()
{
noInterrupts();
pulse_length = pl;
pl = 0;
pulse_marker = pm;
interrupts();
//////////////////////////////////////////////////////////////////////
//Получен некий импульс,//////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
if (pulse_length != 0 && receive_status == FIND_PACKET) {
reciever_ctrl = 1;
//Режим поиска пакета в эфире
if (start_pulse_cnt == 0) {
//Найдена первый "правильный" импульс - длинная единица!
if (pulse_length < (PER_LENGTH) && pulse_length >(THR_LENGTH)) {
start_pulse_cnt = 1;
pre_marker[start_pulse_cnt] = pulse_marker;
pulse_length = 0;
}
}
//Ищем следующие импульсы
else {
//Найден импуль правильной длины
if (pulse_length <= (PER_LENGTH) && pulse_length >= (THR_LENGTH)) {
//Если импульс в правильном месте, то добавляем счётчик найденых стартовых импульсов
if (pulse_marker - pre_marker[start_pulse_cnt] > (PER_LENGTH * 2 - LENGTH_TOLERANCE) && pulse_marker - pre_marker[start_pulse_cnt] < (PER_LENGTH * 2 + LENGTH_TOLERANCE)) {
start_pulse_cnt++;
pre_marker[start_pulse_cnt] = pulse_marker;
pulse_length = 0;
}
///...если в неправильном месте то назначаем его первым
else {
start_pulse_cnt = 1;
pre_marker[start_pulse_cnt] = pulse_marker;
pulse_length = 0;
}
}
else {
//Если импульс неправильной длины, то стоит проверить, а не вышло ли время ожидания правильного импульса
if (pulse_marker - pre_marker[start_pulse_cnt] < (PER_LENGTH * 2 + LENGTH_TOLERANCE)) {
//Время ещё не вышло, скорее всего это помеха. Пропускаем...
pulse_length = 0;
}
else {
//Время вышло, начинаем искать заново
start_pulse_cnt = 0;
pulse_length = 0;
}
}
}
}
if (packet_number == 1 && (millis() - first_packet_end) > 200) { // Если найден первый пакет и вышло вермя ожидания второго
// Не ждём второго, а переходм в режим анализа
receive_status = ANALIZE_PACKETS;
}
//////////////////////////////////////////////////////////////////////
// Сбор данных////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//Если Найдены три длинных единицы и два длинных нуля. Возможно это начало посылки...
if (start_pulse_cnt == 3 && receive_status == FIND_PACKET) {
work_time = millis();
last_premarker = pre_marker[3];
start_pulse_cnt = 0;
if (packet_number == 0) {
collect(collect_data, &data_length);
first_packet_end = millis();
packet_number = 1;
}
else {
collect(collect_data2, &data_length2);
packet_number = 2;
receive_status = ANALIZE_PACKETS;
}
}
if (receive_status == ANALIZE_PACKETS) {
digitalWrite(13, HIGH);
//////////////////////////////////////////////////////////////////////
// Анализ данных////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
bool halfshift;
//Дамп собранных данных
/* if (DEBUG_INFO){
for(int bt = 0; bt < 180; bt++){
Serial.print(collect_data[bt], HEX);
Serial.print(' ');
}
Serial.println(" ");
for(int bt = 0; bt < 180; bt++){
Serial.print(collect_data2[bt],HEX);
Serial.print(' ');
}
Serial.println(" ");
}
*/
get_bits(collect_data);
if (get_data(0, collect_data) > get_data(1, collect_data)) {
data_val = get_data(0, collect_data);
halfshift = 0;
}
else {
data_val = get_data(1, collect_data);
halfshift = 0;
}
if (DEBUG_INFO) {
Serial.print("1) ");
for (int bt = 0; bt < READ_BITS; bt++) {
if (collect_data[bt] > 128 + 1) Serial.print('I');
if (collect_data[bt] < 128 - 1) Serial.print('O');
if (collect_data[bt] == 128 + 1) Serial.print('i');
if (collect_data[bt] == 128 - 1) Serial.print('o');
if (collect_data[bt] == 128) Serial.print('.');
}
Serial.print(" VAL:");
Serial.print(data_val);
//Serial.print(" SIZE:");
//Serial.print(data_length);
Serial.print(" SHIFT:");
Serial.print(halfshift);
}
if (packet_number == 2) {
get_bits(collect_data2);
if (get_data(0, collect_data2) > get_data(1, collect_data2)) {
data_val2 = get_data(0, collect_data2);
halfshift = 0;
}
else {
data_val2 = get_data(1, collect_data2);
halfshift = 1;
}
if (DEBUG_INFO) {
Serial.println(" ");
Serial.print("2) ");
for (int bt = 0; bt < READ_BITS; bt++) {
if (collect_data2[bt] > 128 + 1) Serial.print('I');
if (collect_data2[bt] < 128 - 1) Serial.print('O');
if (collect_data2[bt] == 128 + 1) Serial.print('i');
if (collect_data2[bt] == 128 - 1) Serial.print('o');
if (collect_data2[bt] == 128) Serial.print('.');
}
Serial.print(" VAL:");
Serial.print(data_val2);
//Serial.print(" SIZE:");
//Serial.print(data_length2);
Serial.print(" SHIFT:");
Serial.print(halfshift);
}
}
int correlation = correlate_data(collect_data, collect_data2);
if (DEBUG_INFO) {
Serial.print(" COR: ");
Serial.println(correlation);
}
byte* result_data, result_data_start, aux_data;
if (packet_number == 1) {
result_data = collect_data;
}
else {
if (correlation > 0) {
result_data = collect_data2;
assemble_data(collect_data2, collect_data, &correlation);
}
else {
result_data = collect_data;
correlation = -correlation;
assemble_data(collect_data, collect_data2, &correlation);
}
//Вывод готовой посылки
}
if (DEBUG_INFO) {
Serial.print("RESULT ");
byte* rdt = result_data;
for (int bt = 0; bt < READ_BITS; bt++) {
if (*rdt > 128 + 1) Serial.print('I');
if (*rdt < 128 - 1) Serial.print('O');
if (*rdt == 128 + 1) Serial.print('i');
if (*rdt == 128 - 1) Serial.print('o');
if (*rdt == 128) Serial.print('.');
rdt++;
}
Serial.println(" ");
}
//Обработка посылки
Serial.print("PERIOD: ");
Serial.print(millis() / 40000);
Serial.print(" ");
byte packet[PACKET_LENGTH], valid_p[PACKET_LENGTH];
if (get_info_data(result_data, packet, valid_p)) {
sens_type = get_sensor(packet); //Определяем тип пакета по типу датчика
restore_data(packet, sens_type); // Восстанавливаем данные по типу датчика
crc_c = check_CRC(packet, sens_type); // Проверяем CRC, если оно верно, то все сомнительные биты делаем уверенными
if (crc_c) for (byte www = 0; www < PACKET_LENGTH; www++) valid_p[www] = 0x0f;
Serial.print(" PACKET: ");
for (int q = 0; q < PACKET_LENGTH; q++) Serial.print(packet[q], HEX);
Serial.print(" VALIDITY: ");
for (int q = 0; q < PACKET_LENGTH; q++) Serial.print(valid_p[q], HEX);
}
if (sens_type == THGN132 || sens_type == THN132) {
Serial.print(" TYPE: ");
if (sens_type == THGN132) Serial.print("THGN132N ");
if (sens_type == THN132) Serial.print("THN132N ");
Serial.print("ID: ");
Serial.print(get_id(packet), HEX);
Serial.print(" CHNL: ");
_chnl = get_channel(packet) - 1;
Serial.print(_chnl + 1);
r_type[_chnl] = sens_type;
if (crc_c) r_isreceived[_chnl] = 1;
//......Если получен правильный пакет, сбрасываем таймер
if (crc_c) rcv_time[_chnl] = millis(); //
Serial.print(" BAT: ");
if (crc_c) r_bat[_chnl] = get_battery(packet);
if (r_bat[_chnl]) Serial.print("F "); else Serial.print("e ");
Serial.print("TMP: ");
if (get_temperature_mask(valid_p)) {
if (crc_c) r_tmp[_chnl] = get_temperature(packet);
Serial.print(r_tmp[_chnl], 1);
}
else {
Serial.print("----");
}
Serial.print("C ");
if (sens_type == THGN132) {
Serial.print("HUM: ");
if (get_humidity_mask(valid_p)) {
if (crc_c) r_hmdty[_chnl] = get_humidity(packet);
Serial.print(r_hmdty[_chnl], 1);
}
else {
Serial.print("--");
r_hmdty[_chnl] = 101;
}
Serial.print("%");
}
else Serial.print(" ");
Serial.print(" CRC: ");
if (crc_c) Serial.print("OK ");
else Serial.print("-- ");
Serial.print(" PROC. TIME: ");
Serial.print(millis() - work_time);
Serial.println("ms ");
}
else Serial.println(" WRONG ");
// Возвращаемся к исходному состоянию
receive_status = FIND_PACKET;
packet_number = 0;
start_pulse_cnt = 0;
sens_type = 0;
_chnl = 0;
digitalWrite(13, LOW);
}
//////////////////////////////////////////////////////////////////////
//Здесь записываются остальные процедуры, например те, которые выполняются ежесекундно
//////////////////////////////////////////////////////////////////////
if ((millis() - timer_mark) > 1000) {
{
if (!reciever_status) Serial.println("RECEIVING...");
reciever_status = 1;
}
reciever_ctrl = 0;
}
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
}
PS Надо из этого кода сделать библиотеку, пользоваться в таком виде очень не удобно т.к. автор писал код под конкретный проект. Постараюсь сделать, просто прямощас нет времени.
В нём в таблице известных датчиков THGN132 записан как 1D20h
Все мои Орегон сенсоры выдают 1A2D код, и расположение последующих байтов не совпадает с тем что описано в том документе, думаю он неточен. Почему бы вам просто не выводить то что пришло из эфира, и не делать перетасовку или подмену значений?...
спасибо большое датчик thgn132n видит показания сходятся с базавой станцией. однако я расстроился, что давление принимает основной блок а не датчик с улицы. это для меня ценность всего мониторинга теряется. есть ещё датчик thgn800 посмотрел по сайту тоже не принимает давление. ещё приёмник RF-5V с припаянной антенной не принимает с улицы. пришлось вылазить за окно, доставать датчик. в комнате уже берёт с любого места
Все мои Орегон сенсоры выдают 1A2D код, и расположение последующих байтов не совпадает с тем что описано в том документе, думаю он неточен. Почему бы вам просто не выводить то что пришло из эфира, и не делать перетасовку или подмену значений?...
Не вижу я в этом смысла. От перестановки полубайтов и добавления перед посылкой буковки "А" итоговые данные не изменятся. И ваш вариант и описанный в приведённом мной документе одинаково точны. Интерпретация разная. И никто не мешает вам переписать вывод в Серила в удобном для вас виде.
...однако я расстроился, что давление принимает основной блок а не датчик с улицы. это для меня ценность всего мониторинга теряется. есть ещё датчик thgn800 посмотрел по сайту тоже не принимает давление.
Ну, это вполне логично. Давление что в доме, что на улице одинаковое, если у вас не герметичное помещение, конечно. Расстраиваться не стоит. Датчик давления стоит сущие копейки.
gulin176 пишет:
ещё приёмник RF-5V с припаянной антенной не принимает с улицы. пришлось вылазить за окно, доставать датчик. в комнате уже берёт с любого места
Значит надо экспериметнтировать с антенной. Сделать её на сантиметр-два короче указанного, особенно если у вас она из толстого провода. Или припаять к земле ещё один такой провод в противоположном направлении. Получтся полуволновой вибратор, и можно выиграть до 1.5-2дБ. И антенна обязательно должна торчать перпендикулярно земле.
давление принимает основной блок а не датчик с улицы
Дык, оно одинаковое, если вы не барокамере живете. Поэтому датчик давления в станциях только один и его логично разместить в более комфортных для электроники условиях.
провёл эксперимент. подстроечным винтом на катушке выкрутил на 1\4 оборота и стало принимать в любом месте квартиры куда смог дотянуться приёмником RF-5V привязанным проводами к компьютеру. выкрутил ещё 1\4 оборота и сигнал полностью пропал. теперь записей в сериал типа wrong почти нет
По поводу антенны.Посчитал в NEC2 и вот что получилось. Если принять входное сопротивление приёмика около 40 Ом, то обычный четвертьволновой штырь, который все использют в вид пружинки или куска проволоки, более предпочтителен, чем полуволоновой вибратор, который даёт с учётом рассогласования на 1дБ меньше и более ширкую полосу пропускания. Так что я наверное неправ по поводу целесообразности припаивания второго штыря.
Несколькими постами выше ссылка на проект
Да, в сериал валится какая то абракадабра. Скорость порта???
Вот что в сереале при передаче датчика:
Это повторяется одинаково с каждой посылкой? или по разному?
I и O - это уверенно определённые биты, но их мало и это явно конец посылки. Возможно сигнал слишком слабый, или очень много шума - АРУ отрабатывает очень медленно.
Возможно сильно шумит источник питания, если он импульсный... ПРобовали запитаться от батареи?
"Но я не знаю трогательных маршей" (с).
Либы делать пока не умею, да боюсь и не выйдет. Код завязан на работу с прерыванием и loop().
А так, выпилить из программы дисплей и часы - вопрос получаса . Думаете стоить плодить код и перенести его сюда в базовом варианте?
Ну, если ваш код лучше чем тот что в #113 комментарии - то почему бы и нет )
Библиотеку сделать не сложно, попробую на досуге и пришлю.
Что до кода, то ваш код самый удачный, что я видел на просторах инета.
Доброго времени суток.
Есть датчики Oregon RTGN318.
Как определить, какая версия протокола исползуется?
v 2.2 имхо
v 2.2 имхо
Ясно. Меня смутило наличие RF Clock.
Пытаюсь освоить Ардуино, только для одной цели, приём и отображение/отправка данных с датчиков Oregon.
А чем 2.2 отличается от 2.1?
Простите меня за оффтоп, но я так долго мучался с получением данных от датчиков орегон, что когда случайно наткнулся на сайт Narodmon просто вздохнул. Да, понимаю, не мое, чужое, но какая разница, если датчики вон, в соседнем доме, да еще и с барометром :) Так что забил на свое, пользуюсь чужими данными.
Простите меня за оффтоп, но я так долго мучался с получением данных от датчиков орегон, что когда случайно наткнулся на сайт Narodmon просто вздохнул. Да, понимаю, не мое, чужое, но какая разница, если датчики вон, в соседнем доме, да еще и с барометром :) Так что забил на свое, пользуюсь чужими данными.
Неизвестно где висит датчик у соседа и что он показывает.
Свой надёжнее)) ИМХО
Простите меня за оффтоп, но я так долго мучался с получением данных от датчиков орегон, что когда случайно наткнулся на сайт Narodmon просто вздохнул. Да, понимаю, не мое, чужое, но какая разница, если датчики вон, в соседнем доме, да еще и с барометром :) Так что забил на свое, пользуюсь чужими данными.
Ну вообще-то, люди данные не из Великого Рандома берут, а часто с тех же погодных датчиков Oregon. А как собрать данные с них? - Правильно: Ардуино собирает и шлет на Narodmon.ru
Ну вот, дошли руки. Выкладываю чистый код приёмника.
посмотрите код ошибки почему то.
и что значит #define MHZ 2 //Приёмник подключается к D2
что значит D2?
Ну вот, дошли руки. Выкладываю чистый код приёмника.
С вашим кодом что-то не так... ;)
Ну вот, дошли руки. Выкладываю чистый код приёмника.
С вашим кодом что-то не так... ;)
посмотрите пожалуйста ошибку и куда подключать DATA на UNO
что значит D2?
Digital 2
Цифровой вход номер два!... ) Нумерация которых начинается с ноля. Получается третий от начала ) По поводу ошибки - скорее всего вы неправильно скопировали код с форума, надо через кнопку при наведении мышки на код "посмотреть скопировать код", а не из поста брать.
что значит D2?
Digital 2
Цифровой вход номер два!... ) Нумерация которых начинается с ноля. Получается третий от начала ) По поводу ошибки - скорее всего вы неправильно скопировали код с форума, надо через кнопку при наведении мышки на код "посмотреть скопировать код", а не из поста брать.
код приёмника.
Я посылаю передатчиком такое
1A:2D:40:15:30:24:40:A3:34 (3 21 24.3 34.0 0)
А ваш код выдаёт это
PERIOD: 0 PACKET: 1D204510342043A43300 VALIDITY: FFFFFFFFFFFFFFFFFFFF TYPE: THGN132N
ID: 51 CHNL: 3 BAT: F TMP: 24.3C HUM: 34% CRC: OK PROC. TIME: 619ms
Я посылаю передатчиком такое
1A:2D:40:15:30:24:40:A3:34 (3 21 24.3 34.0 0)
А ваш код выдаёт это
PERIOD: 0 PACKET: 1D204510342043A43300 VALIDITY: FFFFFFFFFFFFFFFFFFFF TYPE: THGN132N
ID: 51 CHNL: 3 BAT: F TMP: 24.3C HUM: 34% CRC: OK PROC. TIME: 619ms
А в чём противоречие? В том, что я байты выдаю в том виде, в котором они приняты в описании протокола?
Да, в первом выдаваемом вами байте 1Ah младший полубайт "A" я не отношу к полученной посылке, т.к. считаю нибл синхронизации частью преамбулы. Он не несёт никакой информации...
С вашим кодом что-то не так... ;)
Да вроде всё нормально. Сигнал шумный, в большинстве полученных посылок не сходится CRC. Но вот в строке 28, например, она сходится. Что-то не так?
посмотрите пожалуйста почему выше по теме выложил ошибку при компиляции. в чём может быть проблема
посмотрите пожалуйста почему выше по теме выложил ошибку при компиляции. в чём может быть проблема
Такое впечатление, что у вас не весь код скопирован. Либо компилятор настроен так, что он не видит функцию, если она в коде вызывается раньше, чем описана. Можно попробовать поставить setup() и loop() в конце скетча
А в чём противоречие? В том, что я байты выдаю в том виде, в котором они приняты в описании протокола?
Ну как бы да, я предполагал что у вас код посылки в "обычном" виде, как у всех ;)
А у вас вместе 1A2D получается 1D20 какой-то... и потом тоже все перепутано...
количество строк совпадает. не пойму что надо поправить слабоват в самостоятельности
Странно. Ваш скетч у меня компилируется.
Попробуйте вот так:
Ну как бы да, я предполагал что у вас код посылки в "обычном" виде, как у всех ;)
А у вас вместе 1A2D получается 1D20 какой-то... и потом тоже все перепутано...
Я руководствовался вот этим документом:
http://wmrx00.sourceforge.net/Arduino/OregonScientific-RF-Protocols.pdf
В нём в таблице известных датчиков THGN132 записан как 1D20h
спасибо залилось. а что было? ну так для общего развития
спасибо залилось. а что было? ну так для общего развития
В ряде случаев компилятор Си может плеваться, если в тексте функция описывается по тексту ниже места её первого вызова. Мы проблему решили переместив тело функции выше её вызова. Хотя грамотнее было бы использовать прототипы функций. Подробнее можно вот тут, например, почитать:
http://www.sbp-program.ru/c/sbp-function-c.htm#pr
посмотрите пожалуйста почему выше по теме выложил ошибку при компиляции. в чём может быть проблема
Автор в предыдущем посте вам правильно ответил - нужно использовать прототипы. Но если вы не хотите морочиться просто перенисите функции setup() и loop() в самый конец кода.
Вот так:
PS Надо из этого кода сделать библиотеку, пользоваться в таком виде очень не удобно т.к. автор писал код под конкретный проект. Постараюсь сделать, просто прямощас нет времени.
В нём в таблице известных датчиков THGN132 записан как 1D20h
Все мои Орегон сенсоры выдают 1A2D код, и расположение последующих байтов не совпадает с тем что описано в том документе, думаю он неточен. Почему бы вам просто не выводить то что пришло из эфира, и не делать перетасовку или подмену значений?...
спасибо большое датчик thgn132n видит показания сходятся с базавой станцией. однако я расстроился, что давление принимает основной блок а не датчик с улицы. это для меня ценность всего мониторинга теряется. есть ещё датчик thgn800 посмотрел по сайту тоже не принимает давление. ещё приёмник RF-5V с припаянной антенной не принимает с улицы. пришлось вылазить за окно, доставать датчик. в комнате уже берёт с любого места
Все мои Орегон сенсоры выдают 1A2D код, и расположение последующих байтов не совпадает с тем что описано в том документе, думаю он неточен. Почему бы вам просто не выводить то что пришло из эфира, и не делать перетасовку или подмену значений?...
Не вижу я в этом смысла. От перестановки полубайтов и добавления перед посылкой буковки "А" итоговые данные не изменятся. И ваш вариант и описанный в приведённом мной документе одинаково точны. Интерпретация разная. И никто не мешает вам переписать вывод в Серила в удобном для вас виде.
...однако я расстроился, что давление принимает основной блок а не датчик с улицы. это для меня ценность всего мониторинга теряется. есть ещё датчик thgn800 посмотрел по сайту тоже не принимает давление.
Ну, это вполне логично. Давление что в доме, что на улице одинаковое, если у вас не герметичное помещение, конечно. Расстраиваться не стоит. Датчик давления стоит сущие копейки.
ещё приёмник RF-5V с припаянной антенной не принимает с улицы. пришлось вылазить за окно, доставать датчик. в комнате уже берёт с любого места
Значит надо экспериметнтировать с антенной. Сделать её на сантиметр-два короче указанного, особенно если у вас она из толстого провода. Или припаять к земле ещё один такой провод в противоположном направлении. Получтся полуволновой вибратор, и можно выиграть до 1.5-2дБ. И антенна обязательно должна торчать перпендикулярно земле.
давление принимает основной блок а не датчик с улицы
Дык, оно одинаковое, если вы не барокамере живете. Поэтому датчик давления в станциях только один и его логично разместить в более комфортных для электроники условиях.
ну так то да но это усложнение кострукции ещё надо датчик добавлять, интегрировать в код
провёл эксперимент. подстроечным винтом на катушке выкрутил на 1\4 оборота и стало принимать в любом месте квартиры куда смог дотянуться приёмником RF-5V привязанным проводами к компьютеру. выкрутил ещё 1\4 оборота и сигнал полностью пропал. теперь записей в сериал типа wrong почти нет
По поводу антенны.Посчитал в NEC2 и вот что получилось. Если принять входное сопротивление приёмика около 40 Ом, то обычный четвертьволновой штырь, который все использют в вид пружинки или куска проволоки, более предпочтителен, чем полуволоновой вибратор, который даёт с учётом рассогласования на 1дБ меньше и более ширкую полосу пропускания. Так что я наверное неправ по поводу целесообразности припаивания второго штыря.
День добрый.
Подскажите пожалуйста.
Есть AtMega 2560.
Прошил ваш скетч.
Подключил приёмник к PWM 2 и GND.
А в Serial ничего не выводится.
Подключил приёмник к PWM 2 и GND.
А +5В куда подключили?... )
На приемнике На Ардуино
1) VCC - +5
2) - GND
3) - PWM 2
4) GND - GND
Попробуйте для начала стандартный код, вдруг приёмник неисправен, или частоты не совпадают.
Подскажите как?
Есть приёмник, есть передатчик, есть ОДНА ATMega 2560.
На приемнике На Ардуино
1) VCC - +5
2) - GND
3) - PWM 2
4) GND - GND
Может надо так:
1) VCC - +5
2) DATA - PWM 2
3) DATA - PWM 2
4) GND - GND
На приемнике На Ардуино
1) VCC - +5
2) - GND
3) - PWM 2
4) GND - GND
Может надо так:
1) VCC - +5
2) DATA - PWM 2
3) DATA - PWM 2
4) GND - GND
Там без разницы. Два средних вывода закорочены между собой