ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Воскресенье
24 ноября
999493 Топик полностью
Гyдвин, волшебник (27.04.2020 17:28, просмотров: 1012) ответил Гyдвин на Понимаю, что лепил из того, что было под рукой, тем не менее... Вот весь "датчик". Для закапывания в землю и подвешивания под крышу одинаковый. Отпилил лишние акселерометр, операционник, датчик вибрации и eeprom. Осталось то, что на картинке :) S1 - геркон. Радиомодуль на CC1101.
Вот прошива, которой достаточно для "курятника". Можно задать необходимые мощность и иитервал посылок. Можно выключить для хранения, поднеся к герметичному датчику магнит на 10 сек. Измеряется и передается температура, напряжение батареи и импеданс (емкость) электродов. У меня прошива обновляется по радио встроенным загрузчиком... 

/

////////////////////////////////////////////////////////////////////////////
#define      VER               1    //  Sensor868
#define      INTERVAL          30   //  в секундах
//#define   RF_POWER        0x40   // -5 dBm
//#define   RF_POWER        0x80   //  4 dBm
//#define   RF_POWER        0xC0   //  12 dBm
#define   RF_POWER        0x50   //  0 dBm


/////////////////////////////////////////////////////////////////////////////
// 3.5V  LF oscillator
// 20C - 10.14 kHz
//-10C -  9.17 kHz
//+45C - 11.29 kHz
//////////////////////////////////

#include "io430.h"
#include "cc110X.h"


#pragma location=0x1000 
__no_init const unsigned short ID; // серийный номер по адресу 0x1000



struct {
unsigned char  xxx;  // для выравнивания структуры 
unsigned char  len;  //
// 6 байт
unsigned short id;  // ID
unsigned short bat; // напр. батареи
unsigned char  imp; // импеданс
signed char    tm;  // температура
} work;



volatile unsigned char   cnt=0;     // счетчик тиков таймера
volatile unsigned char   cnt_off=0; // счетчик для выключения (LPM4)



unsigned int get_bat(void)  
{
     unsigned int batt;

     ADC10CTL1 = INCH_11+ADC10DIV_7+ADC10SSEL_2 ; // MCLK div 7  // AVcc/2
     ADC10CTL0 = SREF_1 + ADC10SHT_2 + REFON + ADC10ON + REF2_5V;
     __delay_cycles(1000);
     ADC10CTL0 |= ENC + ADC10SC;             // Sampling and conversion start
     while (ADC10CTL1 & ADC10BUSY);          // ADC10BUSY?
     batt=ADC10MEM; // напряжение батареи
     ADC10CTL0=0;   // выключим ADC
     ADC10CTL0=0;                    
     ADC10CTL1=0;
     //U(V) = batt * 0.004891
     batt=batt*49/10; // выход в милливольтах  
     return (batt);
}

signed char get_temp(void)
{
     signed long temp;

     ADC10CTL1 = INCH_10 + ADC10DIV_3;         // Temp Sensor ADC10CLK/4
     ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON;
     __delay_cycles(1000);
     ADC10CTL0 |= ENC + ADC10SC;             // Sampling and conversion start
     while (ADC10CTL1 & ADC10BUSY);          // ADC10BUSY?
     temp=ADC10MEM; // температура
     ADC10CTL0=0;   // выключим ADC
     ADC10CTL0=0;                    
     ADC10CTL1=0;
     temp = ((temp - 673) * 423) / 1024;
     return (temp);
}

short get_imp (void)
{
       // здесь замеряем импеданс
       __disable_interrupt();
       TA0CTL = TACLR;                         // сбросим таймер 0
       TA0CTL = TASSEL_3+MC_2;                 // TACLK, cont mode
       TA0CCTL1 = CM_3+CCIS_2+CAP;             // Pos&Neg,GND,Cap
       P2DIR &= ~ BIT2;        
       P2SEL &= ~ BIT2;        
       P2SEL2 |= BIT2;                          
       __delay_cycles(50);                     // интервал измерения
       TA0CCTL1 ^= CCIS0;                      // Захват счетчика CCR1
       __enable_interrupt();
       TA0CTL = 0;                             // Stop Timer_A
       P2SEL2 &= ~BIT2;
       P2DIR |= BIT2;        
       P2OUT &= ~BIT2;
       __enable_interrupt();
       return(TACCR1);                         // импедпнс
}


void send_data(void)
{
         work.id=ID;  
         work.bat=get_bat();  
         work.imp= get_imp();
         work.tm=get_temp();    
         work.len=6;    // длина пакета 6
         TI_CC_On();
         TI_CC_SPIWriteReg(TI_CCxxx0_PATABLE, RF_POWER);  // выставим  RF POWER
         RFSendPacket((char*)&work.len,work.len+1); //передадим пакет
         TI_CC_Off(); // выключим трансивер
}


int main( void )
{
 
   WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer
  
   BCSCTL1 = CALBC1_1MHZ;                    // Set DCO 1 MHz
   DCOCTL  = CALDCO_1MHZ;

   P2SEL=0; //отключим кварц

// запретим возможно использованную в загрузчиках периферию//////
   TA0CTL=0;
   TA1CTL=0;
   UCA0CTL1=0;
   UCB0CTL1=0;
   P1REN=0;
   P2REN=0;
   __disable_interrupt();  
/////////////////////////////////////////////////////////////////
  
  
   // это  для  868
 
   P1OUT = 0x1E; // 0001 1110
   P1DIR = 0xBC; // 1011 1100 // биты 2,3,4 вывод единицы, бит 1 вход с подтяжкой к 1  - для LIS3DH

   P1REN |= BIT0; // подтянем бит0   к GND          // был входа с ОУ (ОУ удалил в этой схеме - жрет лишние 500 nA)
   P1REN |= BIT1; // подтянем бит1   (MISO2) к VCC  // было для lis3d
   P1REN |= BIT6; // подтянем вход   MISO1 CC1101 к GND    

   
   P2OUT = 0x50; // 0101 0000
   P2DIR = 0x57; // 0101 0111 // для CC1101

   BCSCTL3 |= LFXT1S_2;                // LFXT1 = VLO (ACLK) 
 
  
   TI_CC_SPISetup();

   IE1 |= WDTIE;                       // Enable WDT interrupt
   WDTCTL = WDT_ADLY_1000;             // Set Watchdog Timer to exactly 3 s
   __enable_interrupt();
 
  
   ///   MAIN LOOP  //////
   while (1)
    {

      if (cnt==INTERVAL/3) //
      {
        send_data();
        cnt=0;
      } 

      if (!(P2IN & BIT5)) cnt_off++; // геркон замкнут
      if (cnt_off == 3) LPM4;        // геркон замкнут в течении 3 циклов, выключим датчик...
   
      LPM3; // заснем до прерывания 
    }
}

//------------------------------------------------------------

#pragma vector=WDT_VECTOR
__interrupt void watchdog_timer(void)
{
  cnt++;
  LPM3_EXIT;
}