1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

Reading Input Pin

Discussion in 'ARM' started by Ninacs Gergo, Jun 8, 2012.

  1. Ninacs Gergo

    Ninacs Gergo New Member

    Joined:
    Jun 8, 2012
    Messages:
    4
    Likes:
    0
    Hello
    I am using an LM3S9B92 microcontroller and i want to connect it with a TSOP31238 IR receiver to do something when i press some buttons on the remote control.
    I have been reading the documentation for this mC for hours now and I can't read the signal sent by the receiver.
    The output pin of the IR receiver is connected to PA0 pin on the mC
    GND of the receiver is connected to the GND pin on the mC
    VCC of the receiver is connected to a 5V pin on the mC

    I tried this code but it doesn't work



    #define TARGET_IS_TEMPEST_RC1

    #include "inc/lm3s9b92.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "driverlib/debug.h"
    #include "driverlib/gpio.h"
    #include "driverlib/rom.h"
    #include "driverlib/sysctl.h"
    #include "utils/uartstdio.h"

    #define RX_BUFFER_SIZE 16

    int
    main(void)
    {

    volatile unsigned long signal;
    //
    // Set the clocking to run directly from the crystal.
    //
    ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
    SYSCTL_XTAL_16MHZ);

    //
    // Initialize the UART.
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    GPIOPinConfigure(GPIO_PA0_U0RX);
    GPIOPinConfigure(GPIO_PA1_U0TX);
    ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    UARTStdioInit(0);

    UARTprintf("Finished initializing!\n");

    while(1)
    {
    UARTprintf("Value: %x\n",ROM_UARTCharGet(UART0_BASE));/*
    if (ROM_UARTCharsAvail(UART0_BASE))
    {
    UARTprintf("There are chars in the FIFO!\n");
    UARTprintf("The value read is:%x\n", ROM_UARTCharGetNonBlocking(UART0_BASE));
    }
    else
    {
    UARTprintf("There are no chars in the FIFO!\n");
    }

    }
    }

    Can someone tell me what am I doing wrong? or How to properly read the signal sent by the IR receiver?

    Regards,
    Gergo
     
  2. panic mode

    panic mode Well-Known Member

    Joined:
    Nov 8, 2003
    Messages:
    1,637
    Likes:
    38
    Location:
    mississauga
    i would be impressed if you did because i cannot see anything that reads the port...
    inside loop there should be something that reads port a. i only see references to UART0_BASE...
     
  3. Ninacs Gergo

    Ninacs Gergo New Member

    Joined:
    Jun 8, 2012
    Messages:
    4
    Likes:
    0
    The documentation says:
    ROM_UARTCharGet
    Waits for a character from the specified port.
    Prototype:
    long
    ROM_UARTCharGet(unsigned long ulBase)
    Parameters:
    ulBase is the base address of the UART port.
    Description:
    Gets a character from the receive FIFO for the specified port. If there are no characters avail-
    able, this function will wait until a character is received before returning.

    same with:
    ROM_UARTCharGetNonBlocking
    Receives a character from the specified port.
    Prototype:
    long
    ROM_UARTCharGetNonBlocking(unsigned long ulBase)
    Parameters:
    ulBase is the base address of the UART port.
    Description:
    Gets a character from the receive FIFO for the specified port.

    That is why i tried like this. But it doesn't work, so if you could give me a good solution i would appreciate it
     
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. panic mode

    panic mode Well-Known Member

    Joined:
    Nov 8, 2003
    Messages:
    1,637
    Likes:
    38
    Location:
    mississauga

    i know and this is why i posted such reply.
    i am not familiar with that controller but the idea is still the same:

    Code (text):

    main (void){

    // initialize things like peripherals etc.
     configure this
     initiate that
     configure some more
     configure all you need

     // done with init, so now we do loop...

        while (1) {
            value_PA0 = Porta_A & 0x01;  // something like this will read the port, adjust syntax to your platform
            UARTprintf("The value read is:%x\n",value_PA0);  // send value we read from PORTA
            delay(1000); // do not spam.. only send occasional message
       }

    }

     
     
  6. DirtyLude

    DirtyLude Well-Known Member

    Joined:
    Aug 5, 2003
    Messages:
    1,904
    Likes:
    56
    Location:
    Toronto, Canada
    He's thinking that the UART will be receiving a signal from the IR in serial format, not just a single 0 or 1 value. So he's writing on the UART what is received by the UART. I used the Stellaris a long time ago and I never used StellarisWare so I can't comment on whether the code is correct, but remote controls don't send serial data in the format that a UART reads, so your whole premise here is incorrect.

    Different remotes send data in different ways and there is code out there for decoding the remotes signals. You would likely have to steal these functions from code for other microcontrollers, though. It would need to be connected to some kind of timer and interrupt to measure the pulse width of each signal so this might be a little advanced for you at this time.
     
  7. panic mode

    panic mode Well-Known Member

    Joined:
    Nov 8, 2003
    Messages:
    1,637
    Likes:
    38
    Location:
    mississauga
    thanks for your reply, i looked over it again and a bit closer this time and what you say makes sense.
    i should have some code for that worked for one of old remotes but it is for PIC24...
     
  8. panic mode

    panic mode Well-Known Member

    Joined:
    Nov 8, 2003
    Messages:
    1,637
    Likes:
    38
    Location:
    mississauga
    here it is... copy (possibly newer) should be on Reese's website
    Code (text):

    /*
     * "Copyright (c) 2008 Robert B. Reese, Bryan A. Jones, J. W. Bruce ("AUTHORS")"
     * All rights reserved.
     * (R. Reese, reese_AT_ece.msstate.edu, Mississippi State University)
     * (B. A. Jones, bjones_AT_ece.msstate.edu, Mississippi State University)
     * (J. W. Bruce, jwbruce_AT_ece.msstate.edu, Mississippi State University)
     *
     * Permission to use, copy, modify, and distribute this software and its
     * documentation for any purpose, without fee, and without written agreement is
     * hereby granted, provided that the above copyright notice, the following
     * two paragraphs and the authors appear in all copies of this software.
     *
     * IN NO EVENT SHALL THE "AUTHORS" BE LIABLE TO ANY PARTY FOR
     * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
     * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE "AUTHORS"
     * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
     * THE "AUTHORS" SPECIFICALLY DISCLAIMS ANY WARRANTIES,
     * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
     * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
     * ON AN "AS IS" BASIS, AND THE "AUTHORS" HAS NO OBLIGATION TO
     * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
     *
     * Please maintain this header in its entirety when copying/modifying
     * these files.
     *
     *
     */
    #include "pic24_all.h"

    /** \file
     * Decodes bi-phase bitstream from IR remote control as output by IR receiver
     * Protocol is Phillips VCR control, 13 bit command (start bit, toggle bit, 5-bit address, 6-bit data)
     * Timer2 divider must be set such that one bit time does not exceed the timer period.
    */

    #define IR_FIFO_SIZE 32
    volatile uint8 au8_irFIFO[32];
    volatile uint16 u16_irFifoHead = 0;
    volatile uint16 u16_irFifoTail = 0;

    void irFifoWrite(uint8 u8_x) {
      u16_irFifoHead++;
      if (u16_irFifoHead == IR_FIFO_SIZE) u16_irFifoHead = 0;
      au8_irFIFO[u16_irFifoHead] = u8_x;
    }
    uint8 irFifoRead() {
      while (u16_irFifoHead == u16_irFifoTail) {
        doHeartbeat();
      }
      u16_irFifoTail++;
      if (u16_irFifoTail == IR_FIFO_SIZE) u16_irFifoTail = 0;
      return au8_irFIFO[u16_irFifoTail];
    }

    /* no interrupt for Timer2, must be configured so that one bit time does
    not exceed the Timer2 period.
    */
    void  configTimer2(void) {
      T2CON = T2_OFF | T2_IDLE_CON | T2_GATE_OFF
              | T2_32BIT_MODE_OFF
              | T2_SOURCE_INT
              | T2_PS_1_64 ;   //at 40 MHz, approx 420 ms max, 1 tick = 1.6 us
      PR2 = 0xFFFF;                    //must be long enough so that one bit time does not overflow this
      TMR2  = 0;                       //clear timer2 value
      _T2IF = 0;                        //clear interrupt flag
      T2CONbits.TON = 1;               //turn on the timer
    }

    #define TWOTHIRDS_PERIOD_US 1100      //two thirds expected bit period, in microseconds
    #define COMMAND_LENGTH  13            //number of bits expected in IR command
    #define IR_INPUT _RB7                 //using RB9 for IR input

    volatile uint16 u16_lastCapture, u16_thisCapture,u16_delta, u16_twoThirdsPeriodTicks;
    volatile uint8 u8_bitCount,u8_bitCountTotal,u8_currentByte;
    //some one-bit flags
    typedef struct tagFLAGBITS {
    unsigned u1_bitEdge:
      1;
    unsigned u1_bitValue:
      1;
    }FLAGBITS;
    volatile FLAGBITS flags;

    typedef enum  {
      STATE_START_PULSE_FALL = 0,
      STATE_START_PULSE_RISE,
      STATE_BIT_CAPTURE,
      STATE_LAST_EDGE,
    } ICSTATE;

    ICSTATE e_isrICState;

    void _ISRFAST _IC1Interrupt() {
      _IC1IF = 0;
      u16_thisCapture = IC1BUF ;  //always read buffer to prevent overflow
      u16_delta = computeDeltaTicks(u16_lastCapture,u16_thisCapture,PR2);
      u16_lastCapture = u16_thisCapture;
      switch (e_isrICState) {
        case STATE_START_PULSE_FALL:
          e_isrICState = STATE_START_PULSE_RISE;
          break;
        case STATE_START_PULSE_RISE:
          if (u16_delta > u16_twoThirdsPeriodTicks) {
            //error, unexpected long pulse, reset back to start state
            e_isrICState = STATE_START_PULSE_FALL;
          } else {
            //received start pulse, start accumulating bits
            flags.u1_bitEdge = 1;   //next edge contains a bit
            u8_bitCount = 0;
            u8_currentByte = 0;
            flags.u1_bitValue = 1; //first bit is always a '1'
            u8_bitCountTotal = 0;
            e_isrICState = STATE_BIT_CAPTURE;
          }
          break;
        case STATE_BIT_CAPTURE:
          if ((u16_delta > u16_twoThirdsPeriodTicks) || flags.u1_bitEdge) {
            //record this bit
            if ((u16_delta > u16_twoThirdsPeriodTicks)) {
              //bit value has changed if wide pulse
              flags.u1_bitValue = !flags.u1_bitValue;
            }
            if (u8_bitCount != 0)u8_currentByte = u8_currentByte << 1;;
            if (flags.u1_bitValue) u8_currentByte = u8_currentByte | 0x01;
            u8_bitCount++;
            u8_bitCountTotal++;
            flags.u1_bitEdge = 1;  //this was a bit edge
            if (u8_bitCount == 7) {  //received start, toggle, address
              irFifoWrite(u8_currentByte);
              u8_currentByte = 0;
              u8_bitCount = 0;
            }
          }
          flags.u1_bitEdge = !flags.u1_bitEdge;  //next edge is opposite
          if (u8_bitCountTotal == COMMAND_LENGTH) {
            if (u8_bitCount != 0) irFifoWrite(u8_currentByte);  //save last byte
            if (IR_INPUT) e_isrICState = STATE_START_PULSE_FALL;
            else e_isrICState = STATE_LAST_EDGE;   //one more edge to come
          }
          break;
        case STATE_LAST_EDGE:
          e_isrICState = STATE_START_PULSE_FALL;
          break;

        default:
          e_isrICState = STATE_START_PULSE_FALL;
      }
    }


    //configure input capture.
    void configInputCapture1(void) {
      CONFIG_RB7_AS_DIG_INPUT();   //use RB7 for IR Input (must be 5 V tolerant)
      CONFIG_IC1_TO_RP(7);         //map IC1 to RP7/R7
      e_isrICState = STATE_START_PULSE_FALL;
      u16_irFifoHead = 0;
      u16_irFifoTail = 0;
      u16_twoThirdsPeriodTicks = usToU16Ticks(TWOTHIRDS_PERIOD_US, getTimerPrescale(T2CONbits));
      IC1CON = IC_TIMER2_SRC |     //Timer2 source
               IC_INT_1CAPTURE |   //Interrupt every capture
               IC_EVERY_EDGE;      //Interrupt every edge
      _IC1IF = 0;
      _IC1IP = 1;
      _IC1IE = 1;   //enable
    }

    int main (void) {
      uint8 u8_x, u8_y;
      configBasic(HELLO_MSG);
      configTimer2();
      configInputCapture1();

      while (1) {
        u8_x = irFifoRead();
        u8_y = irFifoRead();
        if (u8_x & 0x20) outString("Toggle = 1, ");
        else outString("Toggle = 0, ");
        outString("Addr: ");
        outUint8(u8_x & 0x1F);
        outString(",Cmd: ");
        outUint8(u8_y);
        outString("\n");
      }
    }
     
     
  9. Ninacs Gergo

    Ninacs Gergo New Member

    Joined:
    Jun 8, 2012
    Messages:
    4
    Likes:
    0
    Thank you for your anwers.
    DirtyLude thats exactly the case. I honeslty thought that the receiver will output a byte representation of the signal after it demodulates it and stuff.
    panic mode I'm checking the code right now. Could you write a few main ideas about it? Just so i know what it does
     
  10. panic mode

    panic mode Well-Known Member

    Joined:
    Nov 8, 2003
    Messages:
    1,637
    Likes:
    38
    Location:
    mississauga
    do you know what remote control you want to use? i guess if you use universal remote you could force it to use any supported format. the code uses interrupt that is triggered by both edges of the source signal (interrupt is triggered on both rising and falling edge). timer (in this case it is Timer2) is configured so that it's period is slightly shorter than duration of one bit received from the remote (they used time that is 2/3 of that incomming pulse). when timer expires bit value is captured, decoded and result is put into FIFO.

    main program configures interrupt and timer, then executes loop in which FIFO is read and the values are printed. this is 16bit MCU and timers can be ganged for 32-bit operation (which is not used in this case, we don't need such long time). in 16bit operation and at instruction cycle of 40MHz, max duration of 16-bit timer is about half a second which is much longer than we need.

    Time = (preset +1 )*prescaler/Fcy

    here prescaler is 64 (T2_PS_1_64 is "timer2 prescaler of 1/64")
    preset+1 is 65536 (PR2 = 0xFFFF; )
    and MCU runs at 80MHz so instruction clock is Fcy=40MHz (it is divide by two for this family).

    that gives time

    T= 65536*(1/64)/40000000
    T=0.0256ms
    which corresponds to frequency of 39.0625 kHz
    which is reasonable IR remotes use 38..40kHz.
     
  11. Ninacs Gergo

    Ninacs Gergo New Member

    Joined:
    Jun 8, 2012
    Messages:
    4
    Likes:
    0
    The remote control i will be using is a Winfast Y0400052
     

Share This Page