Citirea datelor transmise de o sonda meteo . - Ateliere de lucru - Forum

 

 
Trebuie sa fii logat pentru a posta Logare


Parola Pierduta?

Cauta in Forumuri:


 






Wildcard Usage:
*    matches any number of characters
%    matches exactly one character

Citirea datelor transmise de o sonda meteo .

Citeste tot articolul

UtilizatorPost

12:27
luni, 20 decembrie 2010


alin

Admin

posturi21

Salutare , zilele acestea o sa intru in posesia unei radiosonde meteo modelul, Vaisala Radiosonde RS80-15GH Digital GPS WeatherStation, ce are urmatoarele caracteristici:

Description……. Weather Radiosonde

Make…………. Vaisala

Type/Model…… RS80-15GH

Voltage……….. Battery

Orogin………… Met Office

Condition……… NEW in sealed bag

Met Office Weather Radiosonde, with 8 channel digital GPS receiver, 403 Mhz Telemetry Transmitter, Barometric, Himidity & Temperature sensors, water activated battery.

Click here for spesifications… http://www.hobeco.net/pdf/RS80_GPS.pdf

View of 403 MHz Telemetry Transmitter with water activated battery.

View of  Humicap, Temperature, and barometric pressure sensors.

View of 8 Channel Digital GPS Receiver.


Intrebarea este : a mai folosit cineva asa ceva , stie cineva protocolul de transmitere al datelor , fiindca vreau sa le colectez cu un arduino si sa le afisez pe un 40X4 (hd44780)


Citeste tot articolul

13:29
luni, 20 decembrie 2010


alin

Admin

posturi21

Se pare ca am gasit un proiect pe aceasta tema dar mai caut. 

Proiectul se poate descarca de aici .

13:01
miercuri, 22 decembrie 2010


alin

Admin

posturi21

Se pare ca ma arpropii de adevar.

Mai trebuie sa imi cumpar un FM Radio Receiver Module QFM-RX1 433MHz FSK, care costa vre o 20 de dolari si recunoaste modul de lucru PSK , de aici de la pagina 239 incepe detalierea unui proiect bazat pe arduino ce colecteaza datele de la o sonda meteo .

Se pare ca mai trebuie sa modific frecventa de receptie a receptorului , sa o duc in plaja de emisie a sondei . 

Smile

Voi ce parere aveti ?

19:39
miercuri, 22 decembrie 2010


alin

Admin

posturi21

WeatherStationReceiver.h

#ifndef WSR_H_
#define WSR_H_
/*————————————————————————————–
 Function Declarations
————————————————————————————–*/

/*————————————————————————————–
 Defines
————————————————————————————–*/
// Type aliases for brevity in the actual code
typedef unsigned int       uint; //16bit
typedef signed int         sint; //16bit

// Some convenience constants
#define  ASCIINUMBASE      0x30  //base value for ascii number '0'
#define  CHAR_CR           0x0D  //carriage return character
#define  CHAR_LF           0x0A  //line feed character

#define WSR_TIMER_PERIOD_US          4                            //Timer1 resolution is 4uS
//master period width filter
#define WSR_PERIOD_FILTER_MIN        ( 300/WSR_TIMER_PERIOD_US)   //min 300uS  allowed through filter
#define WSR_PERIOD_FILTER_MAX        (1800/WSR_TIMER_PERIOD_US)   //max 1800uS allowed through filter
//detection of a 'SHORT', nominal 367uS
#define WSR_SHORT_PERIOD_MIN         WSR_PERIOD_FILTER_MIN        //
#define WSR_SHORT_PERIOD_MAX         ( 600/WSR_TIMER_PERIOD_US)   //max 600uS for a "SHORT"
//detection of a 'LONG', nominal 1464uS
#define WSR_LONG_PERIOD_MIN          (1200/WSR_TIMER_PERIOD_US)   //min 1200uS for a "LONG"
#define WSR_LONG_PERIOD_MAX          WSR_PERIOD_FILTER_MAX        //

//bICP_WSR_State
#define WSR_STATE_IDLE                  0   //any junk, invalid pulse widths or timeout should all return to this state
#define WSR_STATE_LOADING_BITSTREAM     1   //got an initial 0, loading and checking bitstream

#define WSR_BIT_NONE                    0   //
#define WSR_BIT_ZERO                    1   //
#define WSR_BIT_ONE                     2   //

#define WSR_PACKETARRAYSIZE             8   //
#define WSR_TIMESTAMP_BIT_OFFSET       (4*8)//the timestamp takes up the first 32 bits (4 bytes) of the packet
#define WSR_RFPACKETBITSIZE             52  //52 bits in an RF packet (not including the post-generated timestamp)

#define WSR_RESET()                    { bICP_WSR_State = WSR_STATE_IDLE; bICP_WSR_PacketInputBitPointer = WSR_TIMESTAMP_BIT_OFFSET; }

/*————————————————————————————–
 General macros
————————————————————————————–*/
#define INPUT_CAPTURE_IS_RISING_EDGE()    ((TCCR1B & _BV(ICES1)) != 0)
#define INPUT_CAPTURE_IS_FALLING_EDGE()   ((TCCR1B & _BV(ICES1)) == 0)
#define SET_INPUT_CAPTURE_RISING_EDGE()   (TCCR1B |=  _BV(ICES1))
#define SET_INPUT_CAPTURE_FALLING_EDGE()  (TCCR1B &= ~_BV(ICES1))

#define GREEN_TESTLED_IS_ON()       ((PORTD & (1<<PORTD6)) == 0)
#define GREEN_TESTLED_IS_OFF()      ((PORTD & (1<<PORTD6)) != 0)
#define GREEN_TESTLED_ON()          ((PORTD &= ~(1<<PORTD6)))
#define GREEN_TESTLED_OFF()         ((PORTD |=  (1<<PORTD6)))
#define GREEN_TESTLED_TOGGLE()      if(GREEN_TESTLED_IS_ON()){GREEN_TESTLED_OFF();}else{GREEN_TESTLED_ON();}

#define RED_TESTLED_IS_ON()         ((PORTD & (1<<PORTD7)) == 0)
#define RED_TESTLED_IS_OFF()        ((PORTD & (1<<PORTD7)) != 0)
#define RED_TESTLED_ON()            ((PORTD &= ~(1<<PORTD7)))
#define RED_TESTLED_OFF()           ((PORTD |=  (1<<PORTD7)))
#define RED_TESTLED_TOGGLE()        if(RED_TESTLED_IS_ON()){RED_TESTLED_OFF();}else{RED_TESTLED_ON();}

#endif /*WSR_H_*/



WeatherStationReceiver.pde


/**
 * WeatherStationReceiver
 *
 * Receives and decodes a pulse-width and transition encoded RF
 * bitstream, received through a 433MHz receiver module into the PB0
 * Input Capture Pin (ICP).
 *
 * The transmitter is from the La Crosse WS-2355 Weather Station
 * package, the RF transmitter is the integrated thermo/hygro station,
 * (part number WS-2300-25S), and cable connections between the rain and
 * wind sensors are made to the WS-2300-25S unit as it is the central RF
 * transmitter. The cable connected rainfall sensor is part number
 * WS-2300-16. The cable connected wind speed and direction sensor is
 * part number TX20.
 *
 * Copyright 2009 Marc Alexander <marc.alexander@gmail.com>
 * Copyright 2009 Jonathan Oxer <jon@oxer.com.au>
 * http://www.practicalarduino.co…..n-receiver
 */

/**
 * NOTE:
 * The rainfall count may be 11 bits, not 12 bits. Once I saw a 4000+
 * reading on it that was not generated by rainfall pulses, so a higher
 * bit there may mean something else? Still investigating.
 */

/**
 * TODO:
 * 1.   Add: WSR_RESET() call from a dead-time timeout. If no RF
 * activity is received within a few mS, reset the receiver state
 * machine. Currently unsquelched RF noise is resetting it anyway
 * given the receiver model used, but a quiet receiver timeout should be
 * there also. Make sure boundary condition of reset just as new bit /
 * period coming in is not a problem causing loss of packet start if
 * reset happens during first transition/bit in.
 */

/*————————————————————————————–
  Includes
————————————————————————————–*/
#include "WeatherStationReceiver.h"

/*————————————————————————————–
  Variables
————————————————————————————–*/
//———-
// Timer 1 Input capture period and captured event time detection
uint uiICP_CapturedTime;
uint uiICP_PreviousCapturedTime;
uint uiICP_CapturedPeriod;
uint uiICP_PreviousCapturedPeriod;
byte bICP_CapturedPeriodWasHigh;
byte bICP_PreviousCapturedPeriodWasHigh;
unsigned long ulICP_Timestamp_262_144mS;
//———-
byte bICP_WSR_State;                                 //Interpreter state machine
byte bICP_WSR_PacketData[WSR_PACKETARRAYSIZE][4+8];  //incoming RF packet data with 4 byte timestamp at start, already bit reversed to suit.
                                                     //main array size must be ^2, and there may be some other count dependencies in the interpreter.
byte bICP_WSR_PacketInputPointer;           //
byte bICP_WSR_PacketOutputPointer;          //
byte bICP_WSR_PacketInputBitPointer;        //
uint uiICP_WSR_ReceivedPacketCount;         //
//———-
// Saved timestamp at packet receive conversion
unsigned long ulWSR_LastTimestamp_262_144mS;
//———-
// Real world data, latest received and converted by Packet_Converter_WS2355()
byte bWSR_StationTransmitterID;         //
sint siWSR_CurrentTemperature;          //
byte bWSR_CurrentHumidity;              //
byte bWSR_CurrentWindDirection;         //
uint uiWSR_CurrentWindSpeed_m_per_sec;  //
uint uiWSR_RainfallCount;               //
unsigned long ulWSR_Rainfall_mm_x10;
//———-
const char strWindDirection[16][4] = 
{
  "N  ", "NNE", "NE ", "ENE",
  "E  ", "ESE", "SE ", "SSE",
  "S  ", "SSW", "SW ", "WSW",
  "W  ", "WNW", "NW ", "NNW"
};

// Comment out for a normal build
// Uncomment for a debug build
//#define DEBUG

/**
 * Initial configuration
 */
void setup(void)
{
  Serial.begin( 38400 );   //using the serial port at 38400bps for debugging and logging
  Serial.println( "Weather Station Receiver has powered up" );

  Init_Ports();
  Init_RF_Interpreters();
  interrupts();   // Enable interrupts (NOTE: is this necessary? Should be enabled by default)
}

/**
 * Main program loop
 */
void loop(void)
{
  Packet_Converter_WS2355();
}

/**
 * Initialise port initial state and data direction registers
 */
void Init_Ports()
{
  DDRB = 0x2F;   // B00101111
}

/*————————————————————————————–
   Packet_Converter_WS2355
   Inspect, validate and convert any fresh incoming packet data to the latest real world values
      bit      1         2         3         4         5   byte                 1
<-TS  1234567890123456789012345678901234567890123456789012 00112233 4455667788990
      /–||–\/–||–\/–||–\/–||–\/–||–\/–||–\/–| 
   1) 0000100101000010001001111000010100110011101011000001 00000043 0942278533AC1 st:34 ok: 23.3? (533 = 53.3deg, – 30.0deg offset)
                ssiiiiiiii                                                  ttt
   2) 0000100100010010001001111000010100001101101011111000 00000045 091227850DAF8 st:34 ok: 50% RH
                ssiiiiiiii                                                 hh
   3) 0000100100100010001001111000000010001100111101111000 00000046 092227808CF78 st:34 ok: 140 rainfall, 72.5 mm
                ssiiiiiiii        rrrrrrrrrrrr
   4) 0000100101110010001001111000000000001100111111111101 00000047 097227800CFFD st:34 ok: W   (12) wind, speed 0.0m/s 0.0km/h
                ssiiiiiiii
   5) 0000100101000010001001111000010100110011101011000001 00000049 0942278533AC1 st:34 ok: 23.3?
                ssiiiiiiii
   6) 0000100100010010001001111000010100001101101011111000 0000004A 091227850DAF8 st:34 ok: 50% RH
                ssiiiiiiii
   7) 0000100100100010001001111000000010001100111101111000 0000004B 092227808CF78 st:34 ok: 140 rainfall, 72.5 mm
                ssiiiiiiii
   8) 0000100101110010001001111000000000001100111111111101 0000004D 097227800CFFD st:34 ok: W   (12) wind, speed 0.0m/s 0.0km/h
                ssiiiiiiii                wwww        cccc

   cccc = sum of all previous nibbles, from the start of the packet (all 48 preceding bits, 12 nibbles)

   ss   = sensor/packet identifier

   wwww = wind direction
             0 = N   1 = NNE   2 = NE    3 = ENE
             4 = E   5 = ESE   6 = SE    7 = SSE
             8 = S   9 = SSW  10 = SW   11 = WSW 
            12 = W  13 = WNW  14 = NW   15 = NNW

   iiiiiiii = station ID byte. May not be using the top(left) bit of this byte, but is using bits 0-6 at least.
              Every time the WS-2300-25S transmitter batteries are changed, it generates a new semi-random
              station ID. The user is expected to power cycle the WS-2355 receiver which will then
              'lock on' to the next received station ID.

   rrrrrrrrrrrr = 12 (potential?) bits of rainfall count.
               Note that it is up to the data analyser and any time window formatting
               to treat this as a differential value only. It is expected that the value will
               overflow in long term use.

   For more data decoding and locations, see conversion code below

————————————————————————————–*/
void Packet_Converter_WS2355(void)
{
  byte b;
  byte c;
  sint si;

  if( bICP_WSR_PacketInputPointer != bICP_WSR_PacketOutputPointer )
  {
    // A fresh packet is ready to check and convert
    #ifdef DEBUG
    if( (ulICP_Timestamp_262_144mS – ulWSR_LastTimestamp_262_144mS) > 8 )
    {
      // Blank separator line if there has been more than about 2 seconds since the last
      // packet to make it easier to see what belongs with what
      Serial.println();
    }
    #endif

    #ifdef DEBUG
    //print it in binary text out the serial port
    Serial.print("BINARY=");
    for( b = WSR_TIMESTAMP_BIT_OFFSET ; b < (WSR_RFPACKETBITSIZE+WSR_TIMESTAMP_BIT_OFFSET) ; b++ )
    {
      if( (bICP_WSR_PacketData[bICP_WSR_PacketOutputPointer][b >> 3] & (0x80 >> (b&0x07))) != 0 )
      {
        Serial.print( '1', BYTE );
      } else {
        Serial.print( '0', BYTE );
      }
      if( b == 31 )
        Serial.print( ' ', BYTE );   //timestamp seperator
    }
    Serial.println();

    //print it in hex text out the serial port
    //Serial.print( ' ', BYTE );
    Serial.print("HEX=");
    for( b = 0 ; b < ((WSR_RFPACKETBITSIZE+WSR_TIMESTAMP_BIT_OFFSET)/4) ; b += 2 )
    {
      // One nibble at a time
      c = bICP_WSR_PacketData[bICP_WSR_PacketOutputPointer][b >> 1];
      // Top nibble
      Serial.print( (c & 0xF0) >> 4, HEX );
      // Bottom nibble, drop the last one since it's not part of the 52 incoming bits
      if( b < (((WSR_RFPACKETBITSIZE+WSR_TIMESTAMP_BIT_OFFSET)/4)-1) )
      Serial.print( (c & 0x0F), HEX );
      // Timestamp seperator
      if( b == 6 )
        Serial.print( ' ', BYTE );
    }
    Serial.println();
    #endif

    //—————————————————————————-
    if( PacketAndChecksum_OK_WS2355 )
    {
      // Extract the station ID
      b  = (bICP_WSR_PacketData[bICP_WSR_PacketOutputPointer][5] << 4);
      b += (bICP_WSR_PacketData[bICP_WSR_PacketOutputPointer][6] >> 4);
      bWSR_StationTransmitterID = b;
      // Print to serial port
      Serial.print( "STATIONID=" );
      Serial.println( bWSR_StationTransmitterID, DEC );

      // Bits 4 and 5 of this byte are the sensor/packet ID
      b = bICP_WSR_PacketData[bICP_WSR_PacketOutputPointer][5];
      b = (b >> 4) & 0x03;
      switch( b )
      {
        case 0:
        {
          // 0: temperature
          // Sensor/packet ID bits are 0x00, temperature is present in this packet
          // Lower nibble of byte 7 is first temperature digit, take care of 3xx offset
          si  = ((bICP_WSR_PacketData[bICP_WSR_PacketOutputPointer][7] & 0x0F) * 100);
          si += ((bICP_WSR_PacketData[bICP_WSR_PacketOutputPointer][8] >> 4) * 10);
          si +=  (bICP_WSR_PacketData[bICP_WSR_PacketOutputPointer][8] & 0x0F);
          siWSR_CurrentTemperature = (si – 300);

          // Print to serial port with decimal place management
          Serial.print("TEMPERATURE=");
          Serial.print( (siWSR_CurrentTemperature/10), DEC );
          Serial.print( '.', BYTE );
          if( siWSR_CurrentTemperature < 0 ) {
            Serial.println( ((0-siWSR_CurrentTemperature)%10), DEC );
          } else {
            Serial.println( (siWSR_CurrentTemperature%10), DEC );
          }
          break;
        }
        case 1:
        {
          // 1: humidity
          //sensor/packet ID bits are 0x01, humidity is present in this packet
          c  = ((bICP_WSR_PacketData[bICP_WSR_PacketOutputPointer][7] & 0x0F) * 10);
          c +=  (bICP_WSR_PacketData[bICP_WSR_PacketOutputPointer][8] >> 4);
          bWSR_CurrentHumidity = c;

          // Print to serial port with decimal place management
          Serial.print("HUMIDITY=");
          Serial.println( bWSR_CurrentHumidity, DEC );
          break;
        }
        case 2:
        {
          // 2: rainfall
          si  = (sint)(bICP_WSR_PacketData[bICP_WSR_PacketOutputPointer][7] & 0x0F) << 8;
          si +=        bICP_WSR_PacketData[bICP_WSR_PacketOutputPointer][8];
          uiWSR_RainfallCount = (uint)si;

          // Killer (for the Arduino) long multiply here, put in for now to demo real mm of rainfall maths
          ulWSR_Rainfall_mm_x10 = (((unsigned long)uiWSR_RainfallCount * 518) / 100);

          // Print to serial port 
          Serial.print("RAINFALL=");
          Serial.print( (ulWSR_Rainfall_mm_x10/10), DEC );
          Serial.print( '.', BYTE );
          Serial.println( (ulWSR_Rainfall_mm_x10%10), DEC );
          break;
        }
        case 3:
        {
          // 3: wind direction and speed
          // Sensor/packet ID bits are 0x03, wind data is present in this packet
          // Wind direction
          bWSR_CurrentWindDirection = (bICP_WSR_PacketData[bICP_WSR_PacketOutputPointer][8] & 0x0F);

          //wind speed, decimal value is metres per second * 10 (1 fixed deciml place)
          si  = (sint)(bICP_WSR_PacketData[bICP_WSR_PacketOutputPointer][7] & 0x10) << 4;
          si +=      ((bICP_WSR_PacketData[bICP_WSR_PacketOutputPointer][7] & 0x0F) << 4);
          si +=       (bICP_WSR_PacketData[bICP_WSR_PacketOutputPointer][8] >> 4);
          uiWSR_CurrentWindSpeed_m_per_sec = (uint)si;

          // Print to serial port with decimal place management
          Serial.print("WINDDIRECTION=");
          Serial.println( strWindDirection[bWSR_CurrentWindDirection] );

          Serial.print("WINDSPEED=");
          Serial.print( (uiWSR_CurrentWindSpeed_m_per_sec/10), DEC );
          Serial.print( '.', BYTE );
          Serial.println( (uiWSR_CurrentWindSpeed_m_per_sec%10), DEC );
          break;
        }
        default:
        {
          break;
        }
      }
    } else {
      Serial.print( " bad checksum or packet header" );
    }

    //—————————————————————————-
    //save the last timestamp value, currently used for extra CR/LF in serial print
    ulWSR_LastTimestamp_262_144mS = ulICP_Timestamp_262_144mS;
    //—————————————————————————-
    //conversion process done on this packet, move the output pointer along
    bICP_WSR_PacketOutputPointer = ((bICP_WSR_PacketOutputPointer+1)&(WSR_PACKETARRAYSIZE-1));
  }
}


/**
 * PacketAndChecksum_OK_WS2355
 * Return true if packet checksum and inspection is ok
 */
byte PacketAndChecksum_OK_WS2355(void)
{
  byte dataPos;
  byte checksum;

  // First check, last 4 bits of packet are sum of the previous 48 bits (12 nibbles)
  // Don't forget to offset past the timestamp in the first 4 bytes
  checksum = 0;
  for( dataPos = 4; dataPos < 10; dataPos++ )
  {
    // Checked a byte at a time, accumulate into checksum
    checksum += (bICP_WSR_PacketData[bICP_WSR_PacketOutputPointer][dataPos] >> 4);
    checksum += (bICP_WSR_PacketData[bICP_WSR_PacketOutputPointer][dataPos] & 0x0F);
  }
  checksum &= 0x0F;
  if( checksum != (bICP_WSR_PacketData[bICP_WSR_PacketOutputPointer][10] >> 4) )
  {
    return( false );   // Checksum does not match
  }

  // Second check, first byte of packet must be 0x09 ( B00001001 ), appears to be
  // the main identifier for this station
  if( bICP_WSR_PacketData[bICP_WSR_PacketOutputPointer][4] != 0x09 )
  {
    return( false );
  }

  return( true );
}


/**
 * Init_RF_Interpreters
 */
void Init_RF_Interpreters(void)
{
  //Call macros that reset any RF_Interpreter_… state machine and housekeeping values
  WSR_RESET();

  //RF decode ports setup
  //Marc making PB0 (ICP1 Input Capture) a floating input for RX ASK bitstream receiving
  //PB0 was used by the Color LCD/Joystick Shield for the backlight_on signal,
  //R2 has now been removed on the lcd pcb, and Q1 C-E shorted to keep the BL always on
  DDRB  &= ~(1<<DDB0);    //PBO(ICP1) input
  PORTB &= ~(1<<PORTB0);  //ensure pullup resistor is also disabled

  //PORTD6 and PORTD7, GREEN and RED test LED setup
  DDRD  |=  B11000000;      //(1<<PORTD6);   //DDRD  |=  (1<<PORTD7); (example of B prefix)
  GREEN_TESTLED_OFF();      //GREEN test led off
  RED_TESTLED_ON();         //RED test led on
  //PORTD |=  _BV(PORTD6);    //GREEN test led off  (example of _BV macro)
  //PORTD &= ~_BV(PORTD7);    //RED test led on     (example of _BV macro)
  //PORTD |=  (1<<PORTD6);    //GREEN test led off  (example of AVR studio style)
  //PORTD &= ~(1<<PORTD7);    //RED test led on     (example of AVR studio style)

  //———————————————————————————————
  //ICNC1: Input Capture Noise Canceler         On, 4 successive equal ICP1 samples required for trigger (4*4uS = 16uS delayed)
  //ICES1: Input Capture Edge Select            1 = rising edge to begin with, input capture will change as required
  //CS12,CS11,CS10   TCNT1 Prescaler set to 0,1,1 see table and notes above
  TCCR1A = B00000000;   //Normal mode of operation, TOP = 0xFFFF, TOV1 Flag Set on MAX
                        //This is supposed to come out of reset as 0x00, but something changed it, I had to zero it again here to make the TOP truly 0xFFFF
  TCCR1B = ( _BV(ICNC1) | _BV(CS11) | _BV(CS10) );
  SET_INPUT_CAPTURE_RISING_EDGE();
  //Timer1 Input Capture Interrupt Enable, Overflow Interrupt Enable  
  TIMSK1 = ( _BV(ICIE1) | _BV(TOIE1) );
}

/*————————————————————————————–
  TIMER1_OVF_vect
  Timer1 overflow interrupt routine
  262.144 mS TOF period
  If used to feed a 32 bit timestamp counter, (0xFFFFFFFF = 4294967295 count before overlow)
  = 1125899906 seconds = 18764998 minutes = 312749 = 13031 days = 35 years.
————————————————————————————–*/
ISR( TIMER1_OVF_vect )
{
  //increment the 32 bit timestamp counter (see overflow notes above)
  //overflow is allowed as this timestamp is most likely to be used as a delta from the previous timestamp,
  //so if it's used externally in the same 32 bit unsigned type it will come out ok.
  ulICP_Timestamp_262_144mS++;
}

/*————————————————————————————–
  TIMER1_CAPT_vect
  Timer1 input capture interrupt routine
————————————————————————————–*/
ISR( TIMER1_CAPT_vect )
{
  // Immediately grab the current capture time in case it triggers again and
  // overwrites ICR1 with an unexpected new value
  uiICP_CapturedTime = ICR1;

  // GREEN test led on (flicker for debug)
  GREEN_TESTLED_ON();

  //—————————————————————————-
  //immediately grab the current capture polarity and reverse it to catch all the subsequent high and low periods coming in
  //If the initial period filter passes below, this will be inspected to become bICP_EventPolarity
  if( INPUT_CAPTURE_IS_RISING_EDGE() )
  {
    SET_INPUT_CAPTURE_FALLING_EDGE();      //previous period was low and just transitioned high
    bICP_CapturedPeriodWasHigh = false;    //uiICP_CapturedPeriod about to be stored will be a low period      
  } else {
    SET_INPUT_CAPTURE_RISING_EDGE();       //previous period was high and transitioned low
    bICP_CapturedPeriodWasHigh = true;     //uiICP_CapturedPeriod about to be stored will be a high period      
  }

  //—————————————————————————-
  //calculate the current period just measured, to accompany the polarity now stored
  uiICP_CapturedPeriod = (uiICP_CapturedTime – uiICP_PreviousCapturedTime);

  //—————————————————————————-
  // RF Pulse filtering, width test and polarity are analysed now, call the
  // interpreter(s) to analyse them
  RF_Interpreter_WS2355( /*uiICP_CapturedPeriod, bICP_CapturedPeriodWasHigh*/);   //arguments removed and made global


  //—————————————————————————-
  //save the current capture data as previous so it can be used for period calculation again next time around
  uiICP_PreviousCapturedTime           = uiICP_CapturedTime;
  uiICP_PreviousCapturedPeriod         = uiICP_CapturedPeriod;
  bICP_PreviousCapturedPeriodWasHigh   = bICP_CapturedPeriodWasHigh;

  //GREEN test led off (flicker for debug)
  GREEN_TESTLED_OFF();
}

/*————————————————————————————–
  RF_Interpreter_WS2355

  The WS2355 sends 52 bits in a packet and the format is
  A  long high followed by a long low is 0
  A short high followed by a long low is 1

  Not much more is done in this input capture interrupt routine apart from the
  00001 leader check and then loading of the full 52 bit packet.

  bICP_WSR_PacketInputPointer will be moved along when received, the main loop
  called Packet_Converter_WS2355() routine will do the rest of the work
  to check and convert each packet's data content.
————————————————————————————–*/
void RF_Interpreter_WS2355( /*uiICP_CapturedPeriod, bICP_CapturedPeriodWasHigh*/ )
{
  volatile byte b;
  byte bValidBit = false;   // 0=false(WSR_BIT_NONE), 1=WSR_BIT_ZERO, 2=WSR_BIT_ONE

  //#warning A quiet-time timeout must be added to this interepreter, to reset the state machine any time there is a long quiet break in rx

  //discard the captured period if it is out of the expected range, it is noise…
  if( (uiICP_CapturedPeriod >= WSR_PERIOD_FILTER_MIN) && (uiICP_CapturedPeriod <= WSR_PERIOD_FILTER_MAX) )
  {
    //—————————————————————————-
    //PERIOD INITIAL DURATION FILTER OK, CONTINUE
    //—————————————————————————-
    //Check if this is a valid zero(long high) or one(short high) bit, or low period in between
    if( bICP_CapturedPeriodWasHigh )
    {
      //got a high period, could be a valid bit
      if( (uiICP_CapturedPeriod >= WSR_SHORT_PERIOD_MIN) && (uiICP_CapturedPeriod <= WSR_SHORT_PERIOD_MAX) )
      {
        //short high, valid one bit
        bValidBit = WSR_BIT_ONE;
      } else if( (uiICP_CapturedPeriod >= WSR_LONG_PERIOD_MIN) && (uiICP_CapturedPeriod <= WSR_LONG_PERIOD_MAX) ) {
        //long high, valid zero bit
        bValidBit = WSR_BIT_ZERO;
      } else {
        //invalid high period, in the dead zone between short and long bit period lengths
        WSR_RESET();
      }
    }
    //else
    //{
    //   //got a low period, ignored
    //}
    //—————————————————————————-
    //Enter the state machine to load and prepare the incoming packet to bICP_WSR_PacketData[8][4+8]
    if( bValidBit != false )
    {
      switch( bICP_WSR_State )
      {
        case WSR_STATE_IDLE:
        {
          if( bValidBit == WSR_BIT_ZERO )
          {
            //first bit of valid packet is zero (4 zero's, maybe 3)
            //zero out the appropriate bit on the current input packet
            bICP_WSR_PacketData[bICP_WSR_PacketInputPointer][bICP_WSR_PacketInputBitPointer >> 3]
               &= ~(0x01 << (bICP_WSR_PacketInputBitPointer&0x07));
            bICP_WSR_PacketInputBitPointer++;
            bICP_WSR_State = WSR_STATE_LOADING_BITSTREAM;
          } else {
            WSR_RESET();
          }
          break;
        }
        case WSR_STATE_LOADING_BITSTREAM:
        {
          // Potentially valid packet bitstream is on its way in, keep loading it up
          if( bValidBit == WSR_BIT_ZERO )
          {
            bICP_WSR_PacketData[bICP_WSR_PacketInputPointer][bICP_WSR_PacketInputBitPointer >> 3]
               &= ~(0x80 >> (bICP_WSR_PacketInputBitPointer&0x07));
          } else {
            bICP_WSR_PacketData[bICP_WSR_PacketInputPointer][bICP_WSR_PacketInputBitPointer >> 3]
               |=  (0x80 >> (bICP_WSR_PacketInputBitPointer&0x07));
          }

          // Check at appropriate location of the incoming bitstream, if it is valid and throw away if not
          if( bICP_WSR_PacketInputBitPointer == (WSR_TIMESTAMP_BIT_OFFSET + 4) )
          {
            //                               01234    01234
            // Acceptable start to packet is 00001 or 00010 (lost the first 0), could optimise
            // this but will leave with b for now for stability and debugging
            b = bICP_WSR_PacketData[bICP_WSR_PacketInputPointer][4/*bICP_WSR_PacketInputBitPointer >> 3*/];
            b &= B11111000;
            if( b == B00010000 )
            {
              //valid packet 00010 start (with lost first zero), realign and continue
              bICP_WSR_PacketData[bICP_WSR_PacketInputPointer][4/*bICP_WSR_PacketInputBitPointer >> 3*/] = B00001000;
              bICP_WSR_PacketInputBitPointer++;      //move up one past the inserted missing bit
            } else if( b != B00001000 ) {
              //invalid packet start, not 00001, reset
              WSR_RESET();
            }
          }

          // Final check, has the last packet bit (52 bits total) come in? If so, mark this packet
          // as done and move the major packet input pointer along
          if( bICP_WSR_PacketInputBitPointer == (WSR_TIMESTAMP_BIT_OFFSET + (WSR_RFPACKETBITSIZE-1)) )
          {
            // Got full packet, timestamp it for the main loop
            bICP_WSR_PacketData[bICP_WSR_PacketInputPointer][0] = byte(ulICP_Timestamp_262_144mS >> 24);
            bICP_WSR_PacketData[bICP_WSR_PacketInputPointer][1] = byte(ulICP_Timestamp_262_144mS >> 16);
            bICP_WSR_PacketData[bICP_WSR_PacketInputPointer][2] = byte(ulICP_Timestamp_262_144mS >>  8);
            bICP_WSR_PacketData[bICP_WSR_PacketInputPointer][3] = byte(ulICP_Timestamp_262_144mS);
            // Pointer and packet count
            bICP_WSR_PacketInputPointer = ((bICP_WSR_PacketInputPointer+1)&(WSR_PACKETARRAYSIZE-1));//only the lower three bits are used for the 8 entry array
            uiICP_WSR_ReceivedPacketCount++;                                                        //note will overflow and wrap, used for display of progress only
            WSR_RESET();
          }

          // Increment pointer to next new bit location
          bICP_WSR_PacketInputBitPointer++;
          break;
        }
      }
    }
    //—————————————————————————-
  } else {
    //—————————————————————————-
    // PERIOD OUT OF BOUNDS, DISCARD
    // This will throw away any out of range periods and reset the state machine, high or low.
    //—————————————————————————-
    WSR_RESET();
  }
}





About the Arduino Project – Arduino România Forum

Most Users Ever Online: 26

Online acum:
1 Guest

Currently Browsing this Topic:
1 Guest

Statistici Forum

Grupuri4
Forumuri14
Topicuri:18
Posturi:23

Membri:

Sunt 300 membri

Exista %s post nou

Posteri de Top

viorelspinu – 2
hansol – 1

Muta / Sterge Membrilangercs, rdemeter77, viorelspinu, hansol

Administrator;alin (21 Posturi)



 
 Posted by at 17:57