• AVR Freaks

Hot!IO to x/y pins of a touch display~ screwy behavior

Page: 12 > Showing page 1 of 2
Author
JustRob
Super Member
  • Total Posts : 571
  • Reward points : 0
  • Joined: 2008/09/04 12:49:27
  • Location: Hudson Massachusetts United States
  • Status: offline
2020/04/06 10:18:50 (permalink)
0

IO to x/y pins of a touch display~ screwy behavior

I'm using the pic18LF47k42 with MPLABX v5.15, XC8 v2.05 and the ICD3 on a application using a 3.5" 3.3v resistive touch display (see schematic).
 
Note: the lcd spec shows to sense X axis touch connect Y- to GND, Y+ to 3.3v (Vcc = Vref), X- to GND and measure voltage on X+ for touch location.
 
In brief, as I run the code in the debugger the Y+ pin defaults to 3.3V before I configure the IO for the X-, X+, Y- and Y+.  Then, as I step through the adc_init code I set the latches for X-, X+ and Y-  to low and Y+ to high.  Then I configure X- as output, X+ an input.  When I configure Y- as an output the Y+ pin goes to 0.0v.  And finally, when I configure Y+ as an output (with the latch set to 1) the voltage on Y+ goes to 2.9v.
 
There are no hardware shorts between Y- and Y+.  The traces simply go from the pic IO, to the LCD pins and test point pins located close to the LCD pins.
 
Below is the main function where the adc_init() is called along with the adc_init code.
 

// PIC18F47K42 Configuration Bit Settings

// 'C' source line config statements

// CONFIG1L
#pragma config FEXTOSC = ECH // External Oscillator Selection (EC (external clock) above 8 MHz; PFM set to high power)
#pragma config RSTOSC = HFINTOSC_64MHZ// Reset Oscillator Selection (HFINTOSC with HFFRQ = 64 MHz and CDIV = 1:1)

// CONFIG1H
#pragma config CLKOUTEN = OFF // Clock out Enable bit (CLKOUT function is enabled)
#pragma config PR1WAY = ON // PRLOCKED One-Way Set Enable bit (PRLOCK bit can be cleared and set only once)
#pragma config CSWEN = ON // Clock Switch Enable bit (Writing to NOSC and NDIV is allowed)
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor enabled)

// CONFIG2L
#pragma config MCLRE = EXTMCLR // MCLR Enable bit (If LVP = 0, MCLR pin is MCLR; If LVP = 1, RE3 pin function is MCLR )
#pragma config PWRTS = PWRT_OFF // Power-up timer selection bits (PWRT is disabled)
#pragma config MVECEN = ON // Multi-vector enable bit (Multi-vector enabled, Vector table used for interrupts)
#pragma config IVT1WAY = ON // IVTLOCK bit One-way set enable bit (IVTLOCK bit can be cleared and set only once)
#pragma config LPBOREN = OFF // Low Power BOR Enable bit (ULPBOR disabled)
#pragma config BOREN = SBORDIS // Brown-out Reset Enable bits (Brown-out Reset enabled , SBOREN bit is ignored)

// CONFIG2H
#pragma config BORV = VBOR_2P7 // Brown-out Reset Voltage Selection bits (Brown-out Reset Voltage (VBOR) set to 2.7V)
#pragma config ZCD = OFF // ZCD Disable bit (ZCD disabled. ZCD can be enabled by setting the ZCDSEN bit of ZCDCON)
#pragma config PPS1WAY = ON // PPSLOCK bit One-Way Set Enable bit (PPSLOCK bit can be cleared and set only once; PPS registers remain locked after one clear/set cycle)
#pragma config STVREN = ON // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
#pragma config DEBUG = OFF // Debugger Enable bit (Background debugger disabled)
#pragma config XINST = OFF // Extended Instruction Set Enable bit (Extended Instruction Set and Indexed Addressing Mode disabled)

// CONFIG3L
#pragma config WDTCPS = WDTCPS_31// WDT Period selection bits (Divider ratio 1:65536; software control of WDTPS)
#pragma config WDTE = OFF // WDT operating mode (WDT enabled regardless of sleep)

// CONFIG3H
#pragma config WDTCWS = WDTCWS_7// WDT Window Select bits (window always open (100%); software control; keyed access not required)
#pragma config WDTCCS = SC // WDT input clock selector (Software Control)

// CONFIG4L
#pragma config BBSIZE = BBSIZE_512// Boot Block Size selection bits (Boot Block size is 512 words)
#pragma config BBEN = OFF // Boot Block enable bit (Boot block disabled)
#pragma config SAFEN = OFF // Storage Area Flash enable bit (SAF disabled)
#pragma config WRTAPP = OFF // Application Block write protection bit (Application Block not write protected)

// CONFIG4H
#pragma config WRTB = OFF // Configuration Register Write Protection bit (Configuration registers (300000-30000Bh) not write-protected)
#pragma config WRTC = OFF // Boot Block Write Protection bit (Boot Block (000000-0007FFh) not write-protected)
#pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM not write-protected)
#pragma config WRTSAF = OFF // SAF Write protection bit (SAF not Write Protected)
#pragma config LVP = ON // Low Voltage Programming Enable bit (Low voltage programming enabled. MCLR/VPP pin function is MCLR. MCLRE configuration bit is ignored)

// CONFIG5L
#pragma config CP = OFF // PFM and Data EEPROM Code Protection bit (PFM and Data EEPROM code protection disabled)

// CONFIG5H

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>

#include "stdint.h"
#include <stdlib.h>
#include "spi_pic_18f.h"
#include "crystalfontz_3_5_display_18f.h"
#include "graphics_18f.h"
#include "graphic_types_18f.h"
#include "my_resources_18f.h"
#include "thermistor.h"
#include "adc.h"

#define _XTAL_FREQ 64000000 // oscillator frequency for delay function
#define DISPLAY_WIDTH 320
#define DISPLAY_HEIGHT 240

volatile static uint8_t pen_irq = 0;
uint8_t LCD_Xp_CHAN = 0b000000; // adc thermistor 1 channel
uint8_t LCD_Yp_CHAN = 0b000001; // adc thermistor 2 channel

void main(void) {


    
    /*************** CONFIGURE OSCILLATOR *****************/
    // configure oscillator for 32MHz by using the internal oscillator frequency selection register
    OSCFRQbits.FRQ = 0b1000; // set to 64MHz
    
    
    char backrest_temp[20] = "Backrest temp: ";
    char desired_temp[20] = "Desired temp: ";
    char backrest_temp_value[4] = "";
    char desired_temp_value[4] = "";
    char temp_blockout[5] = "&&&&";
    char * p_temp_blockout = temp_blockout;
    char * p_backrest_temp = backrest_temp;
    char * p_desired_temp = desired_temp;
    char * p_backrest_temp_value = backrest_temp_value;
    char * p_desired_temp_value = desired_temp_value;
    extern struct font_s FONT_mkr_15_matchCar_eqCellHt;
    struct font_s * p_temp_font = &FONT_mkr_15_matchCar_eqCellHt;
    uint16_t pos_x_br_temp = (DISPLAY_WIDTH >> 1) - 23;
    uint16_t pos_x_dr_temp = (DISPLAY_WIDTH >> 1) + 9;
    uint16_t pos_y_br_temp = DISPLAY_HEIGHT - 20;
    uint16_t pos_y_dr_temp = DISPLAY_HEIGHT - 28;
    uint16_t d_temp_string_length = 0;
    uint16_t b_temp_string_length = 0;
    uint16_t br_temp_value_ypos = 0;
    uint16_t dr_temp_value_ypos = 0;
    uint16_t temp;
    uint8_t x;
    volatile uint16_t touch_y_position = 0;
    volatile uint16_t adc_value = 0;

    
    d_temp_string_length = gfx_get_text_width(&FONT_mkr_15_matchCar_eqCellHt, p_desired_temp);
    b_temp_string_length = gfx_get_text_width(&FONT_mkr_15_matchCar_eqCellHt, p_backrest_temp);
    
    br_temp_value_ypos = pos_y_br_temp - b_temp_string_length - SPACE_WIDTH;
    dr_temp_value_ypos = pos_y_dr_temp - d_temp_string_length - SPACE_WIDTH;
    
    SPI_init();
    SPI_display_config();
    cf_display_init();
    adc_init();
    
    power_to_y();


 
/* 
 * File: adc_controller.h
 * Author: Rob
 *
 * Created on April 13, 2017, 3:26 PM
 */

#ifndef ADC_CONTROLLER_H
#define ADC_CONTROLLER_H

#ifdef __cplusplus
extern "C" {
#endif

    #include "stdint.h"

#define LCD_Xn_LATCH LATAbits.LA0
#define LCD_Xp_LATCH LATAbits.LA1
#define LCD_Yn_LATCH LATAbits.LA2
#define LCD_Yp_LATCH LATAbits.LA3
    

    
    void adc_init(void);
    uint16_t read_adc_chan(uint8_t);
    void power_to_x();
    void power_to_y();


#ifdef __cplusplus
}
#endif

#endif /* ADC_CONTROLLER_H */


 
// adc_controller.c
/********************************************************************
* Software source for the pic16f1936 ADC *
* *
*********************************************************************/
#include <xc.h>
#include "stdint.h"
#include "adc.h"
#define _XTAL_FREQ 64000000 // oscillator frequency for delay function
#define LCD_Xn_TRIS TRISAbits.TRISA0 // thermistor 1 tris
#define LCD_Xp_TRIS TRISAbits.TRISA1 // thermistor 2 tris
#define LCD_Yn_TRIS TRISAbits.TRISA2 // thermistor 3 tris
#define LCD_Yp_TRIS TRISAbits.TRISA3 // thermistor 3 tris
#define LCD_Xn_ANSEL ANSELAbits.ANSELA0 // set thermistor 1 adc to RA1
#define LCD_Xp_ANSEL ANSELAbits.ANSELA1 // set thermistor 2 adc to RA0
#define LCD_Yn_ANSEL ANSELAbits.ANSELA2 // set thermistor 1 adc to RA1
#define LCD_Yp_ANSEL ANSELAbits.ANSELA3 // set thermistor 2 adc to RA0
extern uint8_t LCD_Xp_CHAN; // adc thermistor 1 channel
extern uint8_t LCD_Yp_CHAN; // adc thermistor 2 channel

void adc_init(){

/*********** INITIALIZE ADC **************/
LCD_Xn_LATCH = 0; // preset x- pin to vss
LCD_Xp_LATCH = 0; // preset x- pin to vss
LCD_Yn_LATCH = 0; // preset x- pin to vss
LCD_Yp_LATCH = 1; // preset x- pin to vss

LCD_Xn_TRIS = 0; // LCD X- io set as output
LCD_Xp_TRIS = 1; // LCD X+ io set as input
LCD_Yn_TRIS = 0; // LCD Y- io set as output
LCD_Yp_TRIS = 0; // LCD Y+ io set as output
/*
LCD_Xn_ANSEL = 0; // set LCD X- pin to analog operation
LCD_Xp_ANSEL = 0; // set LCD X- pin to analog operation
LCD_Yn_ANSEL = 0; // set LCD X- pin to analog operation
LCD_Yp_ANSEL = 0; // set LCD X- pin to analog operation

ADCON0bits.ON = 0; // disable adc
ADCON0bits.CONT = 0; // adc GO is cleared on each conversion
ADCON0bits.CS = 0; // adc clock source is Fosc with divider set by ADCLK
ADCON0bits.FM = 1; // adc result is right justified
ADCON2bits.MD = 0b000; // adc is set for basic mode
ADCLKbits.CS = 0b000011; // conversion clock is Fosc/16 (4MHz)
ADCAPbits.ADCAP = 0b11111; // adc cap is 30pF
ADACQ = 5; // acquisition time is 5 Fosc cycles
ADREFbits.NREF = 0; // adc Vref- = Vss
ADREFbits.PREF = 0b00; // adc Vref+ = Vdd
PIE1bits.ADIE = 0; // adc interrupt disabled (will wait for conversion)
PIR1bits.ADIF = 0; // clear any adc interrupt
// ADCON0bits.ON = 1; // turn on adc
*/
}
 
And finally the power_to_y function:
 

void power_to_y(){
    LCD_Yn_LATCH = 0; // set lcd X- pin to ground
    LCD_Yp_LATCH = 1; // set lcd X+ pin to vcc
}


 
I hope someone sees why the Y- pin affects the Y+ pin
 
Thank you

Attached Image(s)

#1

35 Replies Related Threads

    du00000001
    Just Some Member
    • Total Posts : 3665
    • Reward points : 0
    • Joined: 2016/05/03 13:52:42
    • Location: Germany
    • Status: offline
    Re: IO to x/y pins of a touch display~ screwy behavior 2020/04/06 11:03:16 (permalink)
    +1 (1)
    Hi Rob,
    would you please provide a link to the display's datasheet (or whatever materials are available) ?
    I have some idea but want to make sure prior sending you on a wild goose chase ...

    PEBKAC / EBKAC / POBCAK / PICNIC (eventually see en.wikipedia.org)
    #2
    JustRob
    Super Member
    • Total Posts : 571
    • Reward points : 0
    • Joined: 2008/09/04 12:49:27
    • Location: Hudson Massachusetts United States
    • Status: offline
    Re: IO to x/y pins of a touch display~ screwy behavior 2020/04/06 11:19:25 (permalink)
    #3
    JustRob
    Super Member
    • Total Posts : 571
    • Reward points : 0
    • Joined: 2008/09/04 12:49:27
    • Location: Hudson Massachusetts United States
    • Status: offline
    Re: IO to x/y pins of a touch display~ screwy behavior 2020/04/06 13:43:32 (permalink)
    0
    #4
    du00000001
    Just Some Member
    • Total Posts : 3665
    • Reward points : 0
    • Joined: 2016/05/03 13:52:42
    • Location: Germany
    • Status: offline
    Re: IO to x/y pins of a touch display~ screwy behavior 2020/04/06 14:12:41 (permalink)
    0
    Working on that. Will take a bit of time . . . .

    PEBKAC / EBKAC / POBCAK / PICNIC (eventually see en.wikipedia.org)
    #5
    JustRob
    Super Member
    • Total Posts : 571
    • Reward points : 0
    • Joined: 2008/09/04 12:49:27
    • Location: Hudson Massachusetts United States
    • Status: offline
    Re: IO to x/y pins of a touch display~ screwy behavior 2020/04/06 14:46:18 (permalink)
    0
    Thank you so much sir!
    post edited by JustRob - 2020/04/06 14:48:22
    #6
    du00000001
    Just Some Member
    • Total Posts : 3665
    • Reward points : 0
    • Joined: 2016/05/03 13:52:42
    • Location: Germany
    • Status: offline
    Re: IO to x/y pins of a touch display~ screwy behavior 2020/04/06 15:10:35 (permalink)
    0
    OK - let me elaborate ...
    1. The resistive grid is quite low-resistance. And the microcontroller outputs have some (internal) series resistance. Pins set to LOW often have a lower internal resistance than the same pin set to HIGH.
    2. Might well be that the current throught the resistive grid is high enough to significantly load the H pin - resulting in a voltage significantly lower than the theoretical value of VDD.
      Could also be that the voltage on the pin(s) driven to LOW is somewhat higher than 0 V.
      These would be the end points of the voltage that can be measured, requiring a bit of correction of the formulas to calculate the X and Y coordinates.
    3. When evaluating the touch screen, the first issue is to detect whether there is a touch at all.
    4. Second is to read/calculate the X and Y coordinates.
     
    The following is a code snippet from the Arduino code to be found on the page you referred to. It's looking somewhat different to "standard C code" as it makes use of the Arduino runtime libraries, but the intention of the individual code lines should be clear and it would be quite easy to port it to the C code required for your PIC18.

    uint8_t Read_Touch_Screen(uint16_t *x, uint16_t *y)
    {
      //See if there is a touch.
      //Let YU float, make YD tug high, drive X1 and X2 low.
      //Read Y1, if it is near 5v (~1024), then the screen is not
      //touched. If it is near ground (~50) then the screen is
      //touched.
      uint16_t touched;
      pinMode(TS_YU, INPUT);
      digitalWrite(TS_YU, HIGH);
      pinMode(TS_YD, INPUT_PULLUP);   // If a pullup feature is available on the PIC18: use it.
                                      // Otherwise set TS_YD as an output and drive it HIGH.  du00000001
      digitalWrite(TS_YD, HIGH);
      pinMode(TS_XL, OUTPUT);
      digitalWrite(TS_XL, LOW);
      pinMode(TS_XR, OUTPUT);
      digitalWrite(TS_XR, LOW);
      touched = analogRead(TS_YU);

      //Idle YD as an input
      pinMode(TS_YD, INPUT);
      if (touched < 512)
      {
        //We are touched.
        uint32_t X;
        uint32_t Y;

        //Read X: Set a gradient from 0v to 5v on X, then
        digitalWrite(TS_XR, HIGH);
        X = analogRead(TS_YD); //Could use YU as well

        //Read Y: Reset the gradient on X, set a gradient from
        //0v to 5v on Y, then read the X line to get the Y contact point.
        pinMode(TS_XL, INPUT);
        pinMode(TS_XR, INPUT);

        pinMode(TS_YU, OUTPUT);
        digitalWrite(TS_YU, HIGH);
        pinMode(TS_YD, OUTPUT);
        digitalWrite(TS_YD, LOW);
        Y = analogRead(TS_XL); //Could use XR

        //Idle the Y pins to reduce the current consumption when not scanning
        pinMode(TS_YU, INPUT);
        pinMode(TS_YD, INPUT);

        //Calculate the pixel values, store in the user's pointers.
        *x = ((X - (uint32_t)Xmin) * 320) / ((uint32_t)Xmax - (uint32_t)Xmin);
        *y = 240 - ((Y - (uint32_t)Ymin) * 240) / ((uint32_t)Ymax - (uint32_t)Ymin);

        //Return touched flag.
        return (1);
      }
      else
      {
        //Not touched. Idle the pins that were set to output
        //to detect the touch.
        pinMode(TS_XL, INPUT);
        pinMode(TS_XR, INPUT);
        return (0);
      }
    }

     
    Having commented one scpecific line (added some more commenting to help code understanding), I can remember you driving 2 lines LOW at some point (I didn't dig much deeper). The Arduino sketch tends to drive 2 lines HIGH, but the outcome in itself will be similar.
     
    Hope this transpires and helps

    PEBKAC / EBKAC / POBCAK / PICNIC (eventually see en.wikipedia.org)
    #7
    JustRob
    Super Member
    • Total Posts : 571
    • Reward points : 0
    • Joined: 2008/09/04 12:49:27
    • Location: Hudson Massachusetts United States
    • Status: offline
    Re: IO to x/y pins of a touch display~ screwy behavior 2020/04/07 10:21:18 (permalink)
    0
    Thank you!
     
    I get the code and the approach.  I'll be adapting it and responding.
    #8
    JustRob
    Super Member
    • Total Posts : 571
    • Reward points : 0
    • Joined: 2008/09/04 12:49:27
    • Location: Hudson Massachusetts United States
    • Status: offline
    Re: IO to x/y pins of a touch display~ screwy behavior 2020/04/07 13:27:15 (permalink)
    0
    Ok, I believe the lcd is bad.  This is the short adc_init code:
    void adc_init(){
        
        /*********** INITIALIZE ADC **************/
        LCD_Xn_LATCH = 0; // preset x- pin to vss
        LCD_Xp_LATCH = 0; // preset x- pin to vss
        LCD_Yn_LATCH = 0; // preset x- pin to vss
        LCD_Yp_LATCH = 1; // preset x- pin to vss
        
        LCD_Xn_WPU = 0; // disable lcd_xn weak pullup
        LCD_Xp_WPU = 0; // disable lcd_xp weak pullup
        LCD_Yn_WPU = 0; // disable lcd_yn weak pullup
        LCD_Yp_WPU = 1; // enable lcd_yp weak pullup
        
        LCD_Xn_TRIS = 0; // LCD X- io set as output
        LCD_Xp_TRIS = 1; // LCD X+ io set as input
        LCD_Yn_TRIS = 0; // LCD Y- io set as output
        LCD_Yp_TRIS = 0; // LCD Y+ io set as output

     
    As I step through the previous code
    1) WITHOUT the lcd plugged in the Yp defaults to 3.3v and stays at 3.3v throughout stepping through the above code.
     
    1) WITH the lcd plugged in Yp defaults to 3.28v
    2) When I execute LCD_Yn_TRIS to output the Yp pin of the lcd goes to 0.0v.  (NOTE: this is the tris for the Yn which should not effect the Yp pin)
    3) When I execute LCD_Yp_TRIS (with the latch set to 1) the Yp pin measures 2.8v
     
    There is no short on the circuit board between Yn and Yp.  The traces go just from the lcd connector to the pic io pins.
    #9
    du00000001
    Just Some Member
    • Total Posts : 3665
    • Reward points : 0
    • Joined: 2016/05/03 13:52:42
    • Location: Germany
    • Status: offline
    Re: IO to x/y pins of a touch display~ screwy behavior 2020/04/07 14:44:59 (permalink)
    0
    Hi Rob,
     
    your commenting might need some improvements as it is currently just . . . adding confusion  :)
     
    My guess: your touch grid is fine. And you're single stepping while measuring.
    1. When setting the TRIS of Yn to 0, the TRIS of Yp is still 1. The WPU on this line won't prevent Yp from going low.
    2. Then you set the TRIS of Yp to 0 and Yp recovers to some extend (2.8 V). Which is what's to be expected considering that the touch grid is low-resistance. You might also see Yn rising to maybe 0.1 .. 0.2 V. Nothing wrong with that.
    3. What I'd suggest: as you intend to measure via Xp, set only the WPU of Xn to 1 while scanny for a "touch event present". Once this is evaluated, set this WPU to 0 again. And keep all other WPUs at 0. (If you like, you can have all 4 lines enabled as outputs and set to 0 while not evaluating the touch).
    Basically: everything is fine with the hardware. It's just the software . . .  :)
     

    PEBKAC / EBKAC / POBCAK / PICNIC (eventually see en.wikipedia.org)
    #10
    JustRob
    Super Member
    • Total Posts : 571
    • Reward points : 0
    • Joined: 2008/09/04 12:49:27
    • Location: Hudson Massachusetts United States
    • Status: offline
    Re: IO to x/y pins of a touch display~ screwy behavior 2020/04/11 12:21:39 (permalink)
    0
    So I thought I'd bypass software and deal just with the lcd's hardware. 
     
    I tied 3.3V from my power regulator directly to the X+ pin then in software connected X- and Y- to GND with Y+ set as an input.  I let my code run while I measured with a multimeter the voltage on the Y+ pin.
     
    Then I switched and tied 3.3V from my power regulator directly to the Y+ pin then in software connected X- and Y- to GND with X+ set as an input.  I let my code run while I measured with a multimeter the voltage on the X+ pin.
     
    See attached jpegs of voltage readings.
    So I thought I'd bypass software and deal just with the lcd's hardware. 
     
    I tied 3.3V from my power regulator directly to the X+ pin then in software connected X- and Y- to GND with Y+ set as an input.  I let my code run while I measured with a multimeter the voltage on the Y+ pin.
     
    With those voltage readings it is impossible to distinguish the top-left from the bottom-right.  
     
    Then I switched and tied 3.3V from my power regulator directly to the Y+ pin then in software connected X- and Y- to GND with X+ set as an input.  I let my code run while I measured with a multimeter the voltage on the X+ pin.
     
    See attached jpegs of voltage readings.

    Attached Image(s)

    #11
    du00000001
    Just Some Member
    • Total Posts : 3665
    • Reward points : 0
    • Joined: 2016/05/03 13:52:42
    • Location: Germany
    • Status: offline
    Re: IO to x/y pins of a touch display~ screwy behavior 2020/04/11 14:23:01 (permalink)
    0
    OK. So you've got a coarse estimate for the maximum voltage to be expected when just checking for "any touch at all?" (Xn and Yn driven to GND is only for detecting whether there is a touch at all.)
    The maximum voltage you found was 1.8 V - somewhat higher than the 1.65 V to be expected. But might be the resistances in the touch screen are not that consistent.
     
    Now repeat this with Xp to 3.3 V, Xn to GND, measuring via Yp and/or Yn (having both configured as inputs without a pullup). This will eventually give the X coordinate.
    Then do the same with Yp to 3.3 V, Yn to GND, measuring via Xp and/or Xn to get the Y coordinate.

    PEBKAC / EBKAC / POBCAK / PICNIC (eventually see en.wikipedia.org)
    #12
    JustRob
    Super Member
    • Total Posts : 571
    • Reward points : 0
    • Joined: 2008/09/04 12:49:27
    • Location: Hudson Massachusetts United States
    • Status: offline
    Re: IO to x/y pins of a touch display~ screwy behavior 2020/04/11 14:44:41 (permalink)
    0
    somewhat higher than the 1.65 V to be expected

     
    I don't understand why you expect 1.65V.  From what I understand from the datasheet the voltage at the top should be close to Vcc (Vcc = 3.3V going to X+/Y+).  Would you expect close to 3.3V if ADC Vref- = X- and Vref+ = X+ while Y+ = 3.3V and Y- = GND?
     
    I will try your suggestion tomorrow (or Monday).
    #13
    JustRob
    Super Member
    • Total Posts : 571
    • Reward points : 0
    • Joined: 2008/09/04 12:49:27
    • Location: Hudson Massachusetts United States
    • Status: offline
    Re: IO to x/y pins of a touch display~ screwy behavior 2020/04/17 10:47:12 (permalink)
    0
    I looked at the above code and also incorporated the display manufacturer's suggestions and am now getting more reasonable readings (see jpg) except when I measure the standby Y+ voltage (without touch) the actual pin measures 3.29V (multimeter) while my adc read is measuring 0.0V  (see code below)
     
    This is the main() portion:
        adc_init();
        adc_value = get_standby_val();
        
        while(1){

        }
    }


     
    This is the adc_init() code:
    void adc_init(){
        
        /*********** INITIALIZE ADC **************/
        ADCON0bits.ON = 0; // disable adc
        ADCON0bits.CONT = 0; // adc GO is cleared on each conversion
        ADCON0bits.CS = 0; // adc clock source is Fosc with divider set by ADCLK
        ADCON0bits.FM = 1; // adc result is right justified
        ADCON2bits.MD = 0b000; // adc is set for basic mode
        ADCLKbits.CS = 0b000011; // conversion clock is Fosc/16 (4MHz)
        ADCAPbits.ADCAP = 0b11111; // adc cap is 30pF
        ADACQ = 5; // acquisition time is 5 Fosc cycles
        ADREFbits.NREF = 0; // adc Vref- = Vss
        ADREFbits.PREF = 0b00; // adc Vref+ = Vdd
        PIE1bits.ADIE = 0; // adc interrupt disabled (will wait for conversion)
        PIR1bits.ADIF = 0; // clear any adc interrupt
    // ADCON0bits.ON = 1; // turn on adc

    }


     
    And here is where I read the Y+ voltage (note again: actual Y+ pin measures 3.29V but my adc_value = 0.0V ~ and excuse the excessive variables, they help me troubleshoot)
    uint16_t get_standby_val(){
        
        LAT_XN = 0; // preset x- pin to vss
        LAT_XP = 1; // preset x+ pin to vcc
        
        WPU_XN = 0; // disable lcd_xn weak pullup
        WPU_XP = 1; // enable lcd_xp weak pullup
        
        TRIS_XN = OUTPUT; // preset LCD X- io
        TRIS_XP = OUTPUT; // preset LCD X+ io
        TRIS_YN = INPUT; // preset LCD Y- io
        TRIS_YP = INPUT; // preset LCD Y+ io
        
        ANSEL_XN = DIGITAL; // configure adc X- pin
        ANSEL_XP = DIGITAL; // configure adc X+ pin
        ANSEL_YN = ANALOG; // configure adc Y- pin
        ANSEL_YP = ANALOG; // configure adc Y+ pin

        volatile uint16_t adc_result = 0;
        volatile uint16_t adc_yp = 0;
        volatile uint16_t adc_yn = 0;
        volatile uint16_t adc_result_sum = 0;
        volatile uint16_t adc_avg = 0;
        volatile uint8_t filter_cnt = 64;
        volatile uint8_t i, copy_filter_cnt, shift_amt;
        volatile uint16_t filter_sum, filter_avg;
                
        filter_avg = 0;
        filter_sum = 0;
        copy_filter_cnt = filter_cnt;
        shift_amt = 0;

        // how many times to shift x_sum to get the average
        for (copy_filter_cnt; copy_filter_cnt >= 2; copy_filter_cnt/=2){
            shift_amt++;
        }

        
        ADCON0bits.ON = 0; // adc disabled
        CHAN_YP; // Measure YP
        ADCON0bits.ON = 1; // adc enabled
        __delay_us(100);
        
        // read and average adc channel
        for (i = 0; i < filter_cnt; i++){

            adc_result = 0;

            __delay_us(5);
            ADCON0bits.GO = 1; // start conversion
            while(ADCON0bits.GO); // wait for result

            // read adc
            adc_result = ADRESH << 8;
            adc_result += ADRESL;

            adc_result_sum += adc_result;
            
        } // for loop (adc filter)

        adc_yp = adc_result_sum>>shift_amt;
        adc_result = 0;
        adc_result_sum = 0;
        
        ADCON0bits.ON = 0; // adc disabled
        CHAN_YN; // Measure YN
        ADCON0bits.ON = 1; // adc enabled
        __delay_us(100);
        
        // read and average adc channel
        for (i = 0; i < filter_cnt; i++){

            adc_result = 0;

            __delay_us(5);
            ADCON0bits.GO = 1; // start conversion
            while(ADCON0bits.GO); // wait for result

            // read adc
            adc_result = ADRESH << 8;
            adc_result += ADRESL;

            adc_result_sum += adc_result;
            
        } // for loop (adc filter)

        adc_yn = adc_result_sum>>shift_amt;
        
        ADCON0bits.ON = 0; // adc disabled
        
        adc_avg = adc_yp - adc_yn;

        return adc_avg;

    }


     
     

    Attached Image(s)

    #14
    du00000001
    Just Some Member
    • Total Posts : 3665
    • Reward points : 0
    • Joined: 2016/05/03 13:52:42
    • Location: Germany
    • Status: offline
    Re: IO to x/y pins of a touch display~ screwy behavior 2020/04/17 12:48:15 (permalink)
    0
    Oh, your variable "adc_value" is the return value of get_standby_val()  :)
     
    As you're subtracting the Yn value from the Yp value (within this function) and both values are expected to be the same (1 WPU active, no contact, thus no current/no voltage drop), this is what is to be expected. Whatever the actual voltage on Yp and Yn is.

    PEBKAC / EBKAC / POBCAK / PICNIC (eventually see en.wikipedia.org)
    #15
    JustRob
    Super Member
    • Total Posts : 571
    • Reward points : 0
    • Joined: 2008/09/04 12:49:27
    • Location: Hudson Massachusetts United States
    • Status: offline
    Re: IO to x/y pins of a touch display~ screwy behavior 2020/04/17 14:09:53 (permalink)
    0
    Individually each Yn and Yp adc reading is 0x0017
    I would expect at least Yn or actually Yp (Y+ since it IS 3.29V) to be close to 0x1024
    #16
    du00000001
    Just Some Member
    • Total Posts : 3665
    • Reward points : 0
    • Joined: 2016/05/03 13:52:42
    • Location: Germany
    • Status: offline
    Re: IO to x/y pins of a touch display~ screwy behavior 2020/04/17 14:23:04 (permalink)
    0
    Are you sure you measure at the right instant?
    Try breaking just before starting the ADC conversion and measure then.
     
    But might be you cannot capture the critical event at all:
    During the start of the conversion, there's an internal capacitor charged from the input pin. This does significantly load the input, which might result in a short voltage drop. Writing this: you might be able to capture this drop with an oscilloscope (1:10 probe), triggering on a negative edge with a voltage level of maybe 3.0 V.
    (With the probe attached I expect the drop to be somewhat smaller as the probe inserts some capacitance on its own.)
    To capture this, just break post the ADC conversion.

    PEBKAC / EBKAC / POBCAK / PICNIC (eventually see en.wikipedia.org)
    #17
    JustRob
    Super Member
    • Total Posts : 571
    • Reward points : 0
    • Joined: 2008/09/04 12:49:27
    • Location: Hudson Massachusetts United States
    • Status: offline
    Re: IO to x/y pins of a touch display~ screwy behavior 2020/04/18 09:06:47 (permalink)
    0
    Are you sure you measure at the right instant?
    Try breaking just before starting the ADC conversion and measure then.

    So when you say "break" I am trying to measure the static voltage on RA3 which is 3.29V.  I am doing this measurement before the code goes into the while(1) loop.
     
    Later I will set up the code to trigger an x and y position read upon touch.  I'm just confused on how you want it to break.
     
    #18
    du00000001
    Just Some Member
    • Total Posts : 3665
    • Reward points : 0
    • Joined: 2016/05/03 13:52:42
    • Location: Germany
    • Status: offline
    Re: IO to x/y pins of a touch display~ screwy behavior 2020/04/18 10:54:32 (permalink)
    0
    "break" = "set a breakpoint with the debugger".
     
    And the break(point)s I've been referring to were all meant to be set in the code within get_standby_val().
    Either directly prior the ADC conversion start (to access the voltage when all this LAT/TRIS/WPU fiddling has been done and the voltages have settled) resp. directly after the ADC conversion having completed (to prevent the oscilloscope from retriggering.

    PEBKAC / EBKAC / POBCAK / PICNIC (eventually see en.wikipedia.org)
    #19
    JustRob
    Super Member
    • Total Posts : 571
    • Reward points : 0
    • Joined: 2008/09/04 12:49:27
    • Location: Hudson Massachusetts United States
    • Status: offline
    Re: IO to x/y pins of a touch display~ screwy behavior 2020/04/20 13:27:28 (permalink)
    +2 (2)
    As it turns out I was not setting up my channel correctly.  I was not setting the ADPCH SFR = to my RA3 channel.
     
    Now my code is:
    #define CHAN_YP 0x000011 (this code is in ADC.h)

        ADCON0bits.ON = 0; // adc disabled
        ADPCH = CHAN_YP; // Measure YP
        ADCON0bits.ON = 1; // adc enabled

     
    And now with the lcd not touched yp is at 3.3V and the ADESH + ADRESL = 0x3ff
     
    PROBLEM SOLVED
     
    THANK YOU!!!!
    #20
    Page: 12 > Showing page 1 of 2
    Jump to:
    © 2020 APG vNext Commercial Version 4.5