приемник rf433 и питание

shveshve
Offline
Зарегистрирован: 28.03.2016

Всем привет! Собрал схемку для приема и обработки сигнала от внешнего датчика погодной станции. Скетч взят у товарища, что декодировал протокол, от себя добавил помигивание зеленым диодом в процедуре обработки прерывания. 

При питании от компьютерного USB, или импульсного блока питания от приемника идет случайный шум (зеленый диод, что на активности приемника, постоянно моргает). При питании от батареи - все отлично, пакеты приходят, контрольные суммы совпадают (зеленый диод мигает только перед полученным пакетом).

Пробовал собирать схему на UNO R3 и Iskra Neo (совм. с leonardo), пробовал блоки питания: 5В 1А robiton, 5В 2А от Ipad, 12В от gigabyte brix - схема нормально работает только от батареи крона или сборки из AA.

Пробовал другие скетчи - просто дамп эфира - такая же картина, хаос от блока питания, хорошие редкие сигналы от батареи.

Куда копать?

/*
  Updated code for receiving data from WH2 weather station
  This code implements timeouts to make decoding more robust
  Decodes received packets and writes a summary of each packet to the Arduino's
  serial port
  Created by Luc Small on 19 July 2013.
  Released into the public domain.
*/

// Read data from 433MHz receiver on digital pin 2
#define RF_IN 2
// For better efficiency, the port is read directly
// the following two lines should be changed appropriately
// if the line above is changed.
#define RF_IN_RAW PIND2
#define RF_IN_PIN PIND

// Port that is hooked to LED to indicate a packet has been received
#define LED_PACKET A2
#define LED_ACTIVITY A1

#define COUNTER_RATE 3200-1 // 16,000,000Hz / 3200 = 5000 interrupts per second, ie. 200us between interrupts
// 1 is indicated by 500uS pulse
// wh2_accept from 2 = 400us to 3 = 600us
#define IS_HI_PULSE(interval)   (interval >= 2 && interval <= 3)
// 0 is indicated by ~1500us pulse
// wh2_accept from 7 = 1400us to 8 = 1600us
#define IS_LOW_PULSE(interval)  (interval >= 7 && interval <= 8)
// worst case packet length
// 6 bytes x 8 bits x (1.5 + 1) = 120ms; 120ms = 200us x 600
#define HAS_TIMED_OUT(interval) (interval > 600)
// we expect 1ms of idle time between pulses
// so if our pulse hasn't arrived by 1.2ms, reset the wh2_packet_state machine
// 6 x 200us = 1.2ms
#define IDLE_HAS_TIMED_OUT(interval) (interval > 6)
// our expected pulse should arrive after 1ms
// we'll wh2_accept it if it arrives after
// 4 x 200us = 800us
#define IDLE_PERIOD_DONE(interval) (interval >= 4)
// Shorthand for tests
#define RF_HI (digitalRead(RF_IN) == HIGH)
#define RF_LOW (digitalRead(RF_IN) == LOW)
//#define RF_HI (bit_is_set(RF_IN_PIN, RF_IN_RAW))
//#define RF_LOW (bit_is_clear(RF_IN_PIN, RF_IN_RAW))

// wh2_flags
#define GOT_PULSE 0x01
#define LOGIC_HI  0x02
volatile byte wh2_flags = 0;
volatile byte wh2_packet_state = 0;
volatile int wh2_timeout = 0;
byte wh2_packet[5];
byte wh2_calculated_crc;

ISR(TIMER1_COMPA_vect)
{
  static byte sampling_state = 0;
  static byte count;
  static boolean was_low = false;

  switch (sampling_state) {
    case 0: // waiting
      wh2_packet_state = 0;
      if (RF_HI) {
        digitalWrite(LED_ACTIVITY, HIGH);
        if (was_low) {
          count = 0;
          sampling_state = 1;
          was_low = false;
        }
      } else {
        digitalWrite(LED_ACTIVITY, LOW);
        was_low = true;
      }
      break;
    case 1: // acquiring first pulse
      count++;
      // end of first pulse
      if (RF_LOW) {
        if (IS_HI_PULSE(count)) {
          wh2_flags = GOT_PULSE | LOGIC_HI;
          sampling_state = 2;
          count = 0;
        } else if (IS_LOW_PULSE(count)) {
          wh2_flags = GOT_PULSE; // logic low
          sampling_state = 2;
          count = 0;
        } else {
          sampling_state = 0;
        }
      }
      break;
    case 2: // observe 1ms of idle time
      count++;
      if (RF_HI) {
        if (IDLE_HAS_TIMED_OUT(count)) {
          sampling_state = 0;
        } else if (IDLE_PERIOD_DONE(count)) {
          sampling_state = 1;
          count = 0;
        }
      }
      break;
  }

  if (wh2_timeout > 0) {
    wh2_timeout++;
    if (HAS_TIMED_OUT(wh2_timeout)) {
      wh2_packet_state = 0;
      wh2_timeout = 0;
    }
  }
}

void setup() {

  delay(10000);

  Serial.begin(9600);
  Serial.println("BetterWH2");

  pinMode(LED_PACKET, OUTPUT);
  pinMode(RF_IN, INPUT);

  TCCR1A = 0x00;
  TCCR1B = 0x09;
  TCCR1C = 0x00;
  OCR1A = COUNTER_RATE;
  TIMSK1 = 0x02;

  // enable interrupts
  sei();
}

void loop() {
  static unsigned long old = 0, packet_count = 0, bad_count = 0, average_interval;
  unsigned long spacing, now;
  byte i;

  if (wh2_flags) {
    if (wh2_accept()) {
      // calculate the CRC
      wh2_calculate_crc();

      now = millis();
      spacing = now - old;
      old = now;
      packet_count++;
      average_interval = now / packet_count;
      if (!wh2_valid()) {
        bad_count++;
      }

      // flash green led to say got packet
      digitalWrite(LED_PACKET, HIGH);
      delay(100);
      digitalWrite(LED_PACKET, LOW);

      Serial.print(packet_count, DEC);
      Serial.print(" | ");
      Serial.print(bad_count, DEC);
      Serial.print(" | ");
      Serial.print(spacing, DEC);
      Serial.print(" | ");
      Serial.print(average_interval, DEC);
      Serial.print(" | ");

      for (i = 0; i < 5; i++) {
        Serial.print("0x");
        Serial.print(wh2_packet[i], HEX);
        Serial.print("/");
        Serial.print(wh2_packet[i], DEC);
        Serial.print(" ");
      }
      Serial.print("| Sensor ID: 0x");
      Serial.print(wh2_sensor_id(), HEX);
      Serial.print(" | ");
      Serial.print(wh2_humidity(), DEC);
      Serial.print("% | ");
      Serial.print(wh2_temperature()/10, DEC);
      Serial.print(" | ");
      Serial.println((wh2_valid() ? "OK" : "BAD"));
    }
    wh2_flags = 0x00;
  }
}


// processes new pulse
boolean wh2_accept()
{
  static byte packet_no, bit_no, history;

  // reset if in initial wh2_packet_state
  if (wh2_packet_state == 0) {
    // should history be 0, does it matter?
    history = 0xFF;
    wh2_packet_state = 1;
    // enable wh2_timeout
    wh2_timeout = 1;
  } // fall thru to wh2_packet_state one

  // acquire preamble
  if (wh2_packet_state == 1) {
    // shift history right and store new value
    history <<= 1;
    // store a 1 if required (right shift along will store a 0)
    if (wh2_flags & LOGIC_HI) {
      history |= 0x01;
    }
    // check if we have a valid start of frame
    // xxxxx110
    if ((history & B00000111) == B00000110) {
      // need to clear packet, and counters
      packet_no = 0;
      // start at 1 becuase only need to acquire 7 bits for first packet byte.
      bit_no = 1;
      wh2_packet[0] = wh2_packet[1] = wh2_packet[2] = wh2_packet[3] = wh2_packet[4] = 0;
      // we've acquired the preamble
      wh2_packet_state = 2;
    }
    return false;
  }
  // acquire packet
  if (wh2_packet_state == 2) {

    wh2_packet[packet_no] <<= 1;
    if (wh2_flags & LOGIC_HI) {
      wh2_packet[packet_no] |= 0x01;
    }

    bit_no ++;
    if (bit_no > 7) {
      bit_no = 0;
      packet_no ++;
    }

    if (packet_no > 4) {
      // start the sampling process from scratch
      wh2_packet_state = 0;
      // clear wh2_timeout
      wh2_timeout = 0;
      return true;
    }
  }
  return false;
}


void wh2_calculate_crc()
{
  wh2_calculated_crc = crc8(wh2_packet, 4);
}

bool wh2_valid()
{
  return (wh2_calculated_crc == wh2_packet[4]);
}

int wh2_sensor_id()
{
  return (wh2_packet[0] << 4) + (wh2_packet[1] >> 4);
}

byte wh2_humidity()
{
  return wh2_packet[3];
}

/* Temperature in deci-degrees. e.g. 251 = 25.1 */
int wh2_temperature()
{
  int temperature;
  temperature = ((wh2_packet[1] & B00000111) << 8) + wh2_packet[2];
  // make negative
  if (wh2_packet[1] & B00001000) {
    temperature = -temperature;
  }
  return temperature;
}

uint8_t crc8( uint8_t *addr, uint8_t len)
{
  uint8_t crc = 0;

  // Indicated changes are from reference CRC-8 function in OneWire library
  while (len--) {
    uint8_t inbyte = *addr++;
    for (uint8_t i = 8; i; i--) {
      uint8_t mix = (crc ^ inbyte) & 0x80; // changed from & 0x01
      crc <<= 1; // changed from right shift
      if (mix) crc ^= 0x31;// changed from 0x8C;
      inbyte <<= 1; // changed from right shift
    }
  }
  return crc;
}

 

 

 

 

 

UserDead
UserDead аватар
Offline
Зарегистрирован: 29.11.2015

Эти 433 мГц ненадежные товарищи. У меня такая же беда только от батарейки (пробовал аккум 3,7в). Да еще помехи как я понимаю от пультов автосигнализации. Не раз писали что этот диапазон в частности жилых секторах за*рат. Может стоит попробовать на блоке питания с трансом?! Чисто транс, диодный мост, кондеры и стабилизатор 7805. Никаких импульсов кроме 50 гц не должно быть. И то 50 гц должно по идее гаситься стабилизатором и емкостями в первую очередь. Хотя если была попытка запитать от Зарядного яблока. Должен быть хороший источних. Хотя зарядка есть зарядка.ю а БП есть БП. За компьютер отдельная тема, там все должно быть четко, ровно, надежно. Это же компьютер. Ему стабильное надо. А что если попробовтаь длинный кабель питания и подальше от БП?! Но помоему этих помех не избежать. Если я не прав, будет интересно узнать что-то новое насчет 433 приемни-датчиков.

shveshve
Offline
Зарегистрирован: 28.03.2016

с эфиром в моем конкретном случае все ок - между получением пакетов от датчика погодной станции есть только одна посторонняя активность и в случае работы от батареи она не мешает получать данные по нужному протоколу. очевидно, что проблема в питании
в сети попадаются картинки чужих сборок, где питание идет через usb. как-то им удается при этом работать
http://www.wes.id.au/wp/wp-content/uploads/IMG_0629-Test-Setup-Arduino-Transmitter.jpg

https://giltesa.com/wp-content/uploads/2012/07/arduino-rf-433mhz.jpg

 

UserDead
UserDead аватар
Offline
Зарегистрирован: 29.11.2015

Хочется вспомнить слова одного умного человека из наших краев. Что в сети у нас жуткие помехи (RUS, UA). В отличии от европейского стандарта. Как-то так. Может я и не понимаю о чем говорю. Я вот знаю только одно. У нас делаются устройства которые работают от 220в. И они оооочень долго разрабатывались так как в сети были жуткие помхи и с фильром мучались мама не горюй. Но до ума довели. 

Все таки интересно будет ли работать не безимпульсном трансе как я писал.

shveshve
Offline
Зарегистрирован: 28.03.2016

Буду пробовать, спасибо.

На другом форуме советуют копать в сторону фильтров помех на дросселях.