so I have invented a touch circuit?

Go To Last Post
13 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So I'm working with a very simple project that reads a few pins and if those pins are grounded, I simple show this via an HID (joystick) out put. Essentially the entire idea is to convert a type of controller to a pc controller. Ok long story short I've done about 15 of them ( different types) and I'm working on a new one.

This one requires 3 bits out and 4 bits in , I simply read the 4 bits coming to to the avr, and set the 3 bits out.

pc5 data 0 in
pc4 data 2 in
pc3 data 3 in
pc2 data 4 in
pc1 switch 1 out
pc0 switch 1 out
pb5 switch 1 out

Nothing fancy right. Well I decided I wanted to read pb5 in my init before I set the DDR's to test for a 5 volt line. So using a trick nedward showed me I attempted this. I didnt have any luck so I set my HID out put ( 8 bits) to show the "status" of PINB<<2.
[x][x][pb0][pb1][pb2][pb3][pb4][pb5]
At least that was the idea. I'm currently setting port b like so .

DDRB &= ~0x3F;

Thinking that is going to set all pins to input. Then I can watch the status of all PINs.

I then saw pins 5 and 3 flicker when a cable is connected to them and then stay on with an occasional flicker. If I remove the cable it stops. Then to my surprise I noticed if I touch the pins I get that pin displayed. I first thought to my self, there is no way the avr chip is that sensitive, but knowing I'm new to all of this I put that thought aside. I then tested the data bits and my other hand to ground, and sure enough them to react the same way...Since I'm reading the PORTC instead of PINC I need to be grounded ( I'm guessing ).

So I got curios and opened up another project I did the same way. Inseat there are no switches its all outs. No touch circuit there... So what the heck is going on here?

I cant possibly show all the code but maybe a bit would help.

here is the code I used for the project that does not react to touch.

the init.

unsigned char sreg;
	sreg = SREG;
	cli();
	DDRB = 0; // all inputs
	PORTB |= 0xff; // all pullups enabled
	// all of portC input with pullups
	DDRC &= ~0x3F;
	PORTC |= 0x3F;

	twelveUpdate();

	SREG = sreg;

and the loop.


static void twelveUpdate(void)
{
	unsigned char data[2];
	int x=128,y=128;
	
	readController(data);

	/* Buttons are active low. Invert values. */
	data[0] = data[0] ^ 0xff;
	data[1] = data[1] ^ 0xff;

	if (data[0] & 0x20) { y = 0; } // up
	if (data[0] & 0x10) { y = 255; } //down
	if (data[0] & 0x08) { x = 0; }  // left
	if (data[0] & 0x04) { x = 255; } // right

	last_read_controller_bytes[0]=x;
	last_read_controller_bytes[1]=y;
 	last_read_controller_bytes[2]=0;
}	

From there I just use data and x,y to send info to the HID.

read controller is like so

static void readController(unsigned char bits[2])
{
	bits[0] = PINC;
	bits[1] = PINB;
}

And now for the touch sensitive code.

the init.

unsigned char sreg;
	sreg = SREG;
	cli();
	DDRC = 0x3;  // set switch and data bit directions and pull ups
	PORTC = 0x3;

	DDRB &= ~0x3F; //extra switch is on portB, just use all pins for now(testing)..
	anologUpdate();
	SREG = sreg;

and the loop


static void anologUpdate(void)
{
	unsigned char data= 0,data2= 0;
	int x=128,y=128;


	 if ( pinStatus(1<<2) ) data |= 0x80; // button L

	PORTC &= 0x3E;_delay_ms(10);  //swiches set to  on off
	 if ( pinStatus(1<<5) ) data |= 0x2; // button B 
	 if ( pinStatus(1<<4) ) data |= 0x4; // button C
	 if ( pinStatus(1<<3) ) data |= 0x1; // button A
	 if ( pinStatus(1<<2) ) data |= 0x8; // button start

	PORTC  = ~PORTC | 0x0;_delay_ms(10);  //swiches set to  off on 
	 if ( pinStatus(1<<5) ) y = 0;   //Up
	 if ( pinStatus(1<<4) ) y = 255; //Down
	 if ( pinStatus(1<<3) ) x = 0;   //Left
	 if ( pinStatus(1<<2) ) x = 255;	//Right

	PORTC &= 0x3C; _delay_ms(10); //swiches set to  both off
	 if ( pinStatus(1<<5) ) data |= 0x10; // button Z
	 if ( pinStatus(1<<4) ) data |= 0x20; // button Y
	 if ( pinStatus(1<<3) ) data |= 0x40; // button X
	 if ( pinStatus(1<<2) ) data2 |=0x01; // button R at bottom row

	PORTC  = ~PORTC | 0x3;_delay_ms(10);// set switch back to both on
//HID data.
	last_built_report[0]=x;
	last_built_report[1]=y;
	last_built_report[2]=0x7f;
	last_built_report[3]=0x7f;
	last_built_report[4]=0x7f;
	last_built_report[5]=0x7f;
	last_built_report[6]=data;
	last_built_report[7]=PINB<<2;//TESTING
}

pinStatus like so

static int pinStatus(int pin ){ return ~PINC & pin; }

For anyone to make it this far, you're too kind. Thx for reading. I hope its just some misunderstanding. Be it does give me some cool ideas for touch devices.. If I ever understand what the heck I did to accomplish that?

Last Edited: Sun. Jun 21, 2009 - 10:55 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm a lot older after reading all the above but not wiser. :?

If you don't have (I'm guessinge here) low enough pullup or pulldown resistors then each pin becomes a high impedance input so it can change depending on the phase of the moon, temperature, humidity and definetily touch....no idea if I'm close to making sense either.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

js, Trust me I'm confused beyond scene at the moment, but what you say sounds like the most convincing info I have heard in the past few hours.

When you say "low enough pullup or pulldown resistors " do you mean internal I have a atmega 168-20pu. The only pull up I have external is a 1k on PC%. So its not relevant I would think.

Either way its ok in my other project, same chip.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are you sure the internal pull-up are enabled on all your floating inputs?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
floating inputs?
No I'm not certain, can say I know what that is, going to research it.

Found this, but not sure what bits controls them.

Quote:
and i m getting some random outputs on all pins..

1) Floating inputs are just that--floating. The act of measuring them can change the level. What value would you expect to see on a collection of floating input pins?

So this is sounding convening..

Is my problem the fact I'm only setting PORTC = 0x3; and not setting PORTB pullups?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

To make it easier: If your digital inputs are actvive low then you can use the internal pullup resistors, one for each input.They can be anything from 20-50k, better than several megaohms of a floating input. (you can also use external pullups which you can taylor to you requirements).

If you digital inputs are actvive high then you need to use the external pulldown resistors with the AVR, other chips may give the options of internal pulldown resistors.

I usually use external pullup/pulldown resistors from 4K7 to 10K, in noisy environments you can go lower.

The point is you just cannot leave an input without proper biasing if you want reliable readings. This goes also for analog inputs.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
The point is you just cannot leave an input without proper biasing if you want reliable readings. This goes also for analog inputs.
- Here is where I think my understanding is failing me.

From what I read the avr pins are in Hi-Z state to begin with. In order to reduce noise i'd need to pull up my internal resistors. But my device requires me to keep them pulled down to see the data. So from what you say I need to use the external pulldown resistors. Is there a external on a 168, or do I need to add them my self?

I also was not aware of the fact I could change the impedance of a resister in the avr. I guess need to do some more reading.

Something that confuses me a lot is where programmers set the init pullups with OR , AND. If we are doing the init, why on earth would you want to OR, AND anything. why not just set the pins to what you need? In most cases these are extremely talented folks so there must be a reason for it. I must be failing to understand something here.

PORTB &= ~0x02;
how is that different from
PORTB = 0x3C; ? ( assuming all bits are on to begin with )
If the intent is to set the pullups why woudl we care what the initial status is?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

external, means external... there are no pull-down resistors in the AVR. If the lines need to be pulled low, then you must use external pull-downs, and in this case you would not use the internal pull-ups.

The reason for using OR and AND is so that you are only adjusting the bits of interest. Allowing you to have several init routines incrementally configuring things. If you can guarantee that your assignment won't trash any settings made by other code, then by all means use a blind write.

Also note that PORTB &= ~0x02 is different from PORTB = 0x3C in that the former clears bit 1, leaving all other bits unaffected. The latter sets all the bits at once, in this case all would e high (or pulled-up if DDR is as an input) except bits 0 & 1 which would be left low, (or floating if inputs)

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

glitch, thx that helped. Cleared up a lot if confusion for me.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

High impedance circuits are free to pickup all sorts of signals. A typical AVR input is at least 5Meg input impedance. My guess is that your inputs are toggling at the line frequency rate (50/60HZ depending on where you are).

If you have access to an oscilloscope (typically a 1Meg input impedance), leave the ground lead unconnected and touch the tip of the probe. You will pickup anywhere from 10's of millivolts to possibly a volt or more of line frequency radiation. Damp hands, or pressing harder on the probe will result in more signal. It's this principle that touch lamps use.

I bet if you did an internet search, you could find a project where this technique was used by a microcontroller for a touch lamp controller - probably even a project here in the Freaks.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
I bet if you did an internet search, you could find a project where this technique was used by a microcontroller for a touch lamp controller - probably even a project here in the Freaks.

_ I was think that my self. I remember my father building a touch light switch back in the day. The scope does show a it over 10 mv. Was indeed a neat stubbing I happened on. For me that is.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
so I have invented a touch circuit?
It's quite hard to come up with something original anymore, but don't give up.

Capacitive touch sensing has been around quite a while, and although I don't understand your code, I suspect you are seeing the results of changing a pin from various states (in/out pull-up on/off) in which those changes take time. Touching a pin changes that time to charge/discharge (capacitance of your fingers or toes- but don't try sitting on it). The times are small in human terms, but 10/20/30ms or more would not be unusual (depending on the pull-up value and finger capacitance).

I'm certainly no expert on this subject, but a long time ago (in the early PIC days) I made a gadget with a touch switch. It was simple as can be (I think 1 resistor, 1 'touch wire', and it worked pretty good. Simply detecting how much time it took to charge or discharge the pin was the only code needed.

Fast forward to now, and I think I'm still using this technique (although not for the same purpose)-
http://www.mtcnet.net/~henryvm/4...
(no touch switches in sight, but the technique is being used for a secret purpose).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Google "Hal Philips" invention. Uses AVR as a touch switch.
https://www.avrfreaks.net/index.p...