CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Looking for touch screen controller

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Bcox



Joined: 09 Oct 2007
Posts: 17
Location: Windsor, CT

View user's profile Send private message Visit poster's website

Looking for touch screen controller
PostPosted: Thu Jan 10, 2008 2:57 pm     Reply with quote

Hello all,
I have found discussions about this but no luck with code. I am implementing a 128x64 KS0108 glcd with a 4-wire resistive touch screen. I would like to control this directly from the PIC without using an external touchscreen controller. Has anyone successfully implemented this before? Any tips or code to share before I begin working on this project? I will be using the 18F4520 chip. Thanks for your help!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jan 10, 2008 3:09 pm     Reply with quote

Microchip "mTouch" webpages:
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=2599&param=en531570
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=2599&param=en531567
bwhiten



Joined: 26 Nov 2003
Posts: 151
Location: Grayson, GA

View user's profile Send private message

App Notes
PostPosted: Thu Jan 10, 2008 7:15 pm     Reply with quote

The mTouch is the method I'm using instead of a true Touch Screen LCD.
John P



Joined: 17 Sep 2003
Posts: 331

View user's profile Send private message

PostPosted: Fri Jan 11, 2008 9:15 am     Reply with quote

I've done this. It's a bit tricky, but certainly possible. It involves a lot of changing bits from high to low and in and out of high-z mode. I also used the weak pullups on port b to determine whether anything was pushed, or not. The processor was a PIC16F877A. As you can see, the setting of the various bits is done via a case/switch construction, which was the only way I could keep the various states logically in my head!

The touch screen was wired with the vertical "potentiometer" between porta.3 and portb.4, and the horizontal "potentiometer" between porta.1 and portb.3. The sequence is to set each "pot" in turn with one end pulled high and one low. Meanwhile for the other "pot" you set both ends high-z and read the A/D converter (which has to get its input from one of those pins, obviously). I do some mathematical processing of the data, which you can ignore, though you'll probably have to do some similar stuff. It involves offsetting and scaling the data, and it's not as elegant as it could be, but I quit tinkering with it as soon as it was working right.

The routine needs to be called frequently enough that you get smooth motion of the cursor, but it needs to allow time between calls for the A/D to do a conversion. I just relied on timing and never checked the A/D done bit. The variable "ad_state" needs to be static or global, unless this is part of main().

Edited to say that in my application, what was wanted was a way to determine the location of a "tap" on the screen. A reading is made when the variable "dct", which is incremented once per pass, reaches 132, and then not again until there's been an interval of no contact. You'd need to make some changes if the objective is to track motion.

Code:

      static int ad_state, dct, hold_y;

      if (++ad_state >= 8)
         ad_state = 0;

      switch(ad_state)
      {
         case 0:
            adcon0 = 0x81 + (1 << 3);            // Set up ch 1
            bit_clear(trisa, 3);                  // Make pin 5 an output (low)
            bit_clear(trisb, 4);                  // Make pin 37 an output
            bit_set(portb, 4);                     // Pin 37 is high
            bit_set(trisa, 1);                     // Make pin 3 an input (AD ch 1)
            bit_set(trisb, 3);                     // Make pin 36 high-Z

            break;

         case 1:
            bit_set(adcon0, 2);                     // Start A/D for ch 1
            break;

         case 2:
            hold_y = adresh;                                 // A/D for ch 1 (vertical)
            if (hold_y < 0x10)
               hold_y = 0;
            else
               hold_y -= 0x10;
            if (hold_y > 239)
               hold_y = 239;

            adcon0 = 0x81 + (3 << 3);            // Read ch 3 for first time
            bit_clear(trisa, 1);                  // Make pin 3 an output (low)
            bit_clear(trisb, 3);                  // Make pin 36 an output
            bit_clear(portb, 3);                  // Pin 36 is low
            bit_set(trisb, 4);                     // Pin 37 is high-Z
            bit_clear(rbpu);                        // Port B pullups on, this pulls up 37 and thus 5 also
            bit_set(trisa, 3);                     // Make pin 5 an input (AD ch 3)

            break;

         case 3:
            bit_set(adcon0, 2);                     // Start A/D for ch 3
            break;

         case 4:
            if (adresh > 0x80)                     // Ch 3 reading
            {                                                // No contact, force repeat of states 3 and 4
               ad_state = 2;                           // Next state is 3
               dct = 0;
               break;
            }
            bit_set(portb, 3);                     // Pin 36 is high
            bit_set(rbpu);                           // Port B pullups off
            break;

         case 5:
            bit_set(adcon0, 2);                     // Start A/D for ch 3
            break;

         case 6:
            if (adresh < 0x10)
               i = 0;
            else
               i = adresh - 0x10;
            if (i >= 0xD0)
               i = 0xCF;

            if (dct == 0)
            {
               ypos = hold_y;
               xpos = i;
            }
            else
            {
               ypos += hold_y;
               if (dct < 92)
                  xpos += i;
            }

            if (dct == 132)                        // Mathematically xpos = (x * 92) / 128
            {                                             // Ypos = (y * 132) / 128
               if (bit_test(xpos, 7))
                  xhi++;
               if (bit_test(ypos, 7))
                  yhi++;

               xpos <<= 1;                           // Divide by 128
               xpos >>= 8;
               ypos <<= 1;
               ypos >>= 8;

               xpos <<= 2;   
               ypos <<= 1;
               xpos += 10;
               ypos += 10;
            }

            if (dct < 133)
               dct++;

            adcon0 = 0x81 + 0;                     // Set up ch 0
            break;

         case 7:
            bit_set(adcon0, 2);                     // Start A/D for ch 0, but not used at present
            break;   

//         case 8:         // Not using case 8 at present
//            ch0 = adresh - 0x37;                  // Read channel 0 (speed pot)
            break;
      }
Bcox



Joined: 09 Oct 2007
Posts: 17
Location: Windsor, CT

View user's profile Send private message Visit poster's website

PostPosted: Fri Jan 11, 2008 10:07 am     Reply with quote

Thank you for your help and info. It gives me a good starting place.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group