This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Reading a serial signal

Other Parts Discussed in Thread: MSP430F2274

Hello,

I am trying to read a serial signal from the LHI944 on my msp430f2274 device. The data sheet is here http://search.alkon.net/cgi-bin/pdf.pl?pdfname=/perkin/lhi944.pdf

I am new to C++ and this microcontroller so I have no idea how to read a serial signal

  • This sensor does not provide digital serial interface, it's PIR analog sensor! You shall read slaa283

  • This seems to be exactly what I am looking for! Thank you so much!

  • I have noticed that this operation demands a 16-bit Sigma-Delta analog-to-digital converter. I know the msp430f2274 has a bunch of 10 bit ADC but does it have the 16-bit Sigma-Delta ADC? I've looked through the data sheet but I didn't find it. If it doesn't what do you think I should do? I am hoping to detect human presence. I think the best way would be a non-contact solution. Therefore, I thought an IR sensor would be the best. Do you agree? If I had to get a different kind of IR sensor what do you recommend?

    -Thanks a bunch!

  • Isaac Puckett said:
    I am hoping to detect human presence.

    Depends on distance and application. PIR detectors usually detect IR radiation changes. So it will detect human motion in case it's temperature differ from surroundings. If you want to detect humans having temperature equal to background (like dead ones) or humans that stand still (does not move) - PIR sensor is not for you. Then you need capacitance sensing.

    Isaac Puckett said:
    I have noticed that this operation demands a 16-bit Sigma-Delta analog-to-digital converter.

    Possibly you can do it using SAR ADC too, but most probably you shall add signal preamplifier then. Check signal levels going out of sensor and ADC input signal level range.

  • I think DigiPyro® PYQ 2898 that you asked earlier is a much better detector.
    The interface is digital and much easier to handle.

  • Thank you for your reply,

    I still have the Digipyro PYQ sensor, but I am still having issues reading the signal. I have yet to find information about how to read a serial signal.

  • The Application Note you cited earlier has enough information about how to read the digitized data. I can help you to read them. But I do not know how to process that digital information after they are read.

    This is already many steps ahead of your current thinking. You haven't figure out how to digitize it yet if you use your current approach. After that, you still need to process the digital readings.

  • Here was the code cited for the digipyro IR sensor from http://www.perkinelmer.com/CMSResources/Images/44-6541APP_HowtouseTripleChannelDigiPyro.pdf:

    // DL: Direct Link Interface of the Triple DigiPyro®. A bidirectional single wire interface,
    // directly connectable to most µC’s I/O- pins.
    // V2.03 10.12.2007 read the Triple Channel DigiPyro® synchronous
    // µC: Atmel ATMega8, 6MHz: Port C0 (ADC0, Pin 23) connected to Int0 (Pin 32) external Interrupt.
    // DPDL High will cause an Interrupt and so start reading the Triple Channel DigiPyro®
    // immediately when ADC has finished
    // read 3 x 14 Bit from Triple DigiPyro®, 0=Channel 1, 1= Channel 0, 2=Temperature

    #include <mega8.h>
    // Definitions for DigiPyro Port C Bit 0
    #define DDPDL DDRC.0 // port C bit 0 data direction bit
    #define DPDL_OUT PORTC.0 // port C bit 0 output
    #define DPDL_IN PINC.0 // port C bit 0 input
    #define PORT_IS_INP 0
    #define PORT_IS_OUTP 1

    int Data[3]; // Data[0]: Channel 1, Data[1]: Channel 0, Data[2]: Temperature (triple: 3 x 14 Bit)

    // ****************************************************************************
    // External Interrupt 0 service routine
    //
    // read DigiPyro

    for (i=0; i<3; i++)
    for (j=0; j<14; j++)

    configure Pin as output;
    set DL low for >200 ns;
    set DL high for >200 ns;
    configure Pin as input;
    Data(i) <<=1; // shift Bits left
    if (DL == high) Data(i)++; // read 1
    Data(0) = 0; // Ch 1
    Data(1) = 0; // Ch 0
    Data(2) = 0; // Temp
    Interruptroutine Triple DigiPyro()
    configure Pin as input;
    DL
    High?
    wait > 25µs
    configure Pin as output;
    set Pin low for >200ns;
    configure Pin as input;
    return ();

    interrupt [EXT_INT0] void ext_int0_isr(void)

    { // Disable External Interrupt0 until DigiPyro is read.
    MCUCR &= 0xFC; // Ext. Interrupt 0 disabled while reading
    digipyro();
    MCUCR |=0x03; // Ext. Interrupt 0 enabled
    }

    // ****************************************************************************
    // function: digipyro()
    //
    // do not read asynchronous to the ADC- converter. Read the interface interrupt-driven: High = new data
    // this routine should preferrably be used by the interrupt routine only.
    // use Data[] for access to the DigiPyro after interrupt
    // reads DigiPyro data: Data[0]: Channel 1, Data[1]: Channel 0, Data[2]: Temperature

    void digipyro(void)
    { int i, j, k, pir_data;

    pir_data = 0;
    DDPDL = PORT_IS_INP; // Configure PORT CO as Input for
    // DigiPyro Direct Link Interface (DPDL)

    while(DPDL_IN == 0); // wait for DPDL = high - max. 1 ms (in regular mode)
    for (j=0; j < 60; j++); // wait appr. 30 µsec (tS)

    for (k = 0; k < 3; k++) // 3 Channels
    { for (i=0; i < 14; i++) // 14 Bits each
    { DPDL_OUT = 0; // Set DPDL = Low, Low level duration must be > 200 ns (tL)
    DDPDL = PORT_IS_OUTP; // Configure PORT C0 DPDL as Output
    DPDL_OUT = 0; // Set DPDL = Low, Low level duration must be > 200 ns (tL)
    #asm("nop")
    DPDL_OUT = 1; // Set DPDL = High, High level duration must be > 200 ns (tH)
    #asm("nop")
    DDPDL = PORT_IS_INP; // Configure PORT C0 DPDL as Input
    #asm("nop")
    #asm("nop")

    for(j=0; j < 2; j++); // wait appr. 5 µsec to ensure proper low level reading (tbit)
    pir_data <<=1;
    if (DPDL_IN) pir_data++; // sample bit
    }
    Data[k] = pir_data;
    pir_data = 0;
    }
    DDPDL = PORT_IS_OUTP; // Configure PORT C0 DPDL as Output
    DPDL_OUT = 0; // Set DPDL = Low, Low level duration must be > 200 ns (tL)
    DDPDL = PORT_IS_INP; // Configure PORT CO DPDL as Input
    return ();
    }

    void main(void)

    { // Port C initialization
    // Func6=In Func5=Out Func4=Out Func3=Out Func2=Out Func1=In Func0=In
    // State6=T State5=0 State4=0 State3=0 State2=0 State1=T State0=T
    PORTC = 0x00;
    DDRC = 0x3C;

    // External Interrupt initialization
    // INT0: On
    // INT0 Mode: Rising Edge, DigiPyro triggers Interrupt to be immediately read after conversion
    GICR |= 0x40;
    MCUCR &= 0xFC;
    GIFR |= 0x40;

    SFIOR |= 0x04; // no pullups: PUD=1 (Bit#2)

    #asm("sei") // Global enable interrupts

    int channel1, channel0, temperature; // DigiPyro data 3 x 14 Bit

    channel1 = Data[0];
    channel0 = Data[1];
    temperature = Data[2];

    // ... your code ...

    }


    I am trying to translate this Atmega code to work on my msp430f2274 device. Being new to C++ as well to this device is posing some issues. I have noticed that the Digipyro IR sensor has a bidirectional digi-link wire that communicates to the device. In the code above I have noticed that the atmega has a DigiPyro Direct Link Interface (DPDL) port. Is this something that I can still do on my device? 

  • I wrote an example code for reading PYQ-2898 with MSP430F2274.

    // Example code for reading PYQ-2898 with MSP430F2274
    // Direct Link of PYQ-2898 is connected to P1.2 of MSP430F2274
    // P2.1 of MSP430F2274 is used to show SMCLK
    
    #include <msp430f2274.h>
    
    // Data[0]: Channel 1, Data[1]: Channel 0, Data[2]: Temperature
    unsigned Data[3];
    
    int main( void )
    {
      signed int idx, bit;
      // Stop watchdog timer to prevent time out reset
      WDTCTL = WDTPW + WDTHOLD;
      // Set up DCO at calibrated 16 MHz
      DCOCTL = 0;
      BCSCTL1 = CALBC1_16MHZ;
      DCOCTL = CALDCO_16MHZ;
      // Show SMCLK at P2.1
      P2SEL |= BIT1;
      P2DIR |= BIT1;
      
      // Endless loop to read PYQ-2898
      while (1)
      {
        while (P1IN & BIT2);        // wait for DL low
        while ((P1IN & BIT2)==0);   // wait for it to go high
        __delay_cycles (26*16);     // *** Ref Point # 1 ***
        for (idx = 0; idx <3; idx++)
        {
          Data[idx] = 0xFFFC;       // invalid data
          for (bit = 13; bit >= 0; bit--)
          {
            P1OUT &= ~BIT2;
            P1DIR |= BIT2;
            __delay_cycles (1);     // *** Ref Point # 2 ***
            P1OUT |= BIT2;
            __delay_cycles (1);     // *** Ref Point # 3 ***
            P1DIR &= ~BIT2;
            __delay_cycles (2*16);  // *** Ref Point # 4 ***
            Data[idx] <<= 1;
            if (P1IN & BIT2) Data[idx]++;     
          }
        }
        __delay_cycles (1);         // *** Ref Point # 5 ***
      }
    }
    

    I have neither PYQ-2898 nor MSP4302274, thus the code is un-tested. I suggest that you use IAR KickStart to try it.

    After you successfully Build the Project, you can use FET Debugger to Download and Debug.

    Do not use single-step. Set up a break-point at the line marked "*** Ref Point # 5 *** and run. If the Debugger does not allow you add that break-point, it is probably because it already has a break-point at the entrance of main(). In that case, disable that one and then you can set one at Ref Point # 5.

    When it reaches Ref Point # 5, Data[..] should have one set of reading of PYQ-2898.

    If you have an oscilloscope, it will be very helpful to capture the waveform at the Direct Link (at P1.2). You should set the time scale to 20 or 25 usec/cm and trigger on rising edge.

  • Thanks for your reply,

    Your code looks outstanding, but I am seeing some slight issues. I have noticed that you declared P2.1 before we go into the Digiread loop. When I run my code it gets stuck waiting for P1.2 to go high. Did you mean P2.1? If so, I will change all the P1.2 to P2.1. Thanks again for your help!

  • No.

    // Direct Link of PYQ-2898 is connected to P1.2 of MSP430F2274
    // P2.1 of MSP430F2274 is used to show SMCLK

    I do not have data-sheet of PYQ-2898. According to the limited info in the AP you cited in your other posting, PYQ-2898 will drive the Direct Link high when it finishes with an ADC conversion. The code you cited also says that signal will go high. The code for MSP430 is just waiting for that. Did you connect power pin and ground pin of PYQ-2898?

  • I ended up getting a sensor from http://learn.adafruit.com/pir-passive-infrared-proximity-motion-sensor/. It sends out a 3V DC signal when the PIR is triggered. Overall it is much more user friendly.

**Attention** This is a public forum