0

Non-Linear functions

Posted by Keith on Jan 20, 2010 in Uncategorized

One of the great ironies of engineering is that we try to control a non-linear world with a linear circuitry.  Entire text books have been written just on the subject of linearization of sensors, and until recently, this linearization usually entailed complex op-amp circuits and tedious/expensive calibration techniques in manufacturing.

However, now that we are firmly entrenched in the age of software; this traditionally hardware based problem has become a new headache for programmers.  So, how do we handle non-linearity in software?  Well, there are two common solutions; piecewise linear approximations, and curve fitting.

Piecewise linear approximati ons take the non-linear curve and break it into multiple segments that can be represented by a straight line.  For example, you can approximate a sine function with a set of equations like the following;

for-blog

Now the approximation is not very good, but it does fit the general outline of a sine wave.    In addition, their can be significant discontinuities where the segments meet, which is all dependant upon the number of segments, or pieces, and how closely the linear segments approximates the function over their range.

Curve fitting is the process of finding a equation that fits the non-linear function over a restricted range of values, for example, an approximation of the same sine wave, for the range 0-180 degrees, is the following function;

Y = -0.00808+(0.0217*X)-(0.000121*X2)

The new function is closer, but even with all the floating point math, it still has an error of 3-4% over the range of the function, and the more cyclic the function, the harder it will become to find one function that fits the entire range.

Usually, for periodic functions, the function is approximated over its period, or some segment of its period and the result is applied like the linear segments in piece wise linear approximations.  That is, for 0-180, the function is used as is; for 180-360, we subtract 180 from the input, and multiply the output by -1.

Regardless of the method used, it is important to determine the overall system error, over the range that the system will be used.  Spread sheets are particularly handy for this, just enter a column of reasonable data in the first column, copy your function into the second column, and calculate the error in the third column.  If the error is more than you can live with, then increase the number of pieces in the approximation, or increase the order of the curve fit. 

Input

Ideal

Curve Fit

Error

 

PWL

Error

0

0.0000

-0.00808

1%

 

0

0%

30

0.5000

0.53402

-3%

 

0.333333

17%

60

0.8660

0.85832

1%

 

0.666667

20%

90

1.0000

0.96482

4%

 

1

0%

120

0.8660

0.85352

1%

 

0.666667

20%

150

0.5000

0.52442

-2%

 

0.333333

17%

180

0.0000

-0.02248

2%

 

0

0%

 
0

Inductive Touch Demonstration

Posted by admin on Jan 14, 2010 in Uncategorized

Check out this new video!

Inductive Touch Demonstration

Tags: ,

 
0

K.I.S.S.

Posted by admin on Dec 1, 2009 in Uncategorized

The other day I was playing with the idea of building an iambic keyer, using the new PIC16F1827 from Microchip. My dad (W7GP) enjoys making code keys and I have a friend up in Colorado that still uses Morse on the air. Besides, I had promised myself that I would relearn the code and actually use it on the air (N7KGC). In addition, the PIC16F1827 was a perfect choice for the project due to a wealth of CCPs and a new modulation peripheral.

I was completely caught up in the wild enthusiasm of a new project; I had figured out the timing, allocated the necessary pins and resources for the tone generation, and was considering what kind of user interface when I hit a brick wall over the question of how to handle code speed, dit-to-dah weighting, and tone volume.

All three functions had typically been handled by a potentiometers, they gave the user a simple interface that was intuitive and simple to handle while actually using the keyer. In fact, all three functions were typically adjusted while generating dits and dahs until the rate, volume, and weighting “felt right.”

The problem was, in the back of my mind, I was stuck on the misconception that because the keyer was digital, the user interface also had to be digital. And, try as I might, I couldn’t come up with a simple system that would work as well as the old fashioned pots.

A menu driven user interface with UP and DOWN buttons was going to be too slow, and would require the user to look at the display. Touch button sliders would work, but if I accidentally touched one, I could mess up their settings and I would need some kind of Braille guide to keep my fingers aligned on the slider. Encoders would also work, but the cost of both the encoders and the code space required to decode them would not be worth it.

It was about this time, that I suddenly saw the light, and promptly gave my self a swift kick in the cerebellum for being dense. The answer was the KISS principal, Keep-It-Simple-Stupid. The potentiometers had the right feel, they retained their setting when the power was removed, and they provided a simple visual feedback and they were simple to interface. All I needed to do was digitize the wiper voltage with an ADC channel, and I would have my simple, cheep, and intuitive user interface to my digital keyer.

So, I setup a Timer0 interrupt for 4.096mS, and dropped a simple statemachine into the ISR to periodically sample the three ADC inputs. The results were stuffed into the appropriate variables, and whiz-bang, I had the perfect interface. I could even adjust the offset and slope in code to provide convenient values.

No complex commands to decode, no expensive graphics LCD module to show a virtual knob, and I even saved pins. Keeping It simple not only saved resources, it also saved about 20 pages worth of user’s manual explaining how to set the rate, weighting, and volume of the keyer.

Of course their was one annoying intermittent problem. Every once in a while I would get a glitch on the pot I was adjusting. I the value would momentarily jump by ¼ or ½ of full scale. After several hours of hair pulling and 2 attempts to digitally filter the values, it finally dawned on me, I was using the values out of the variables at exactly the same time that the ISR was updating the values. The result was a 01FF when the values rolled over from 0FF to 100, or a 000 output when I rolled over 100 to 0FF. The solution was to simple; turn off the interrupts, copy the values into a separate set of variables, and then turn the interrupts back on. Basically, I created the software equivalent of double buffering.

While the final result did take some extra storage space and required a small increase in code size, it was still far smaller than any of the other alternatives and a lot more convenient to use.

 
1

PC productivity tools for embedded programmers

Posted by Rawin on Nov 22, 2009 in General

As embedded programmers, we all write firmware. Small projects are not so hard to manage. But as projects get bigger and with more than just one programmer involved, it’s time to look around for tools to help keep the team’s productivity high.

To write this blog, I simply dig into my computer and pick out the tools I use often. Here they are, in random order…

Comparing files, well, the worst way to do is to open up two source files and compare them by eyeballing. Comparing files is often needed when working with other people, you want to see what others have changed. Even by yourself, you may want to compare the file you are using today against the file from 5 days ago. Something was working, now it’s not, what’s changed? I personally use Beyond Compare from, http://www.scootersoftware.com. This is not free, but very affordable. It can compare files, folders, you name it. It shows result in a very intuitive manner, can’t live without it. Alternatively, you could use WinMerge, http://winmerge.org. WinMerge is free. Check them out.

Next is version control. At work, the team I’m with uses SVN, http://subversion.tigris.org, and TortoiseSVN, http://tortoisesvn.tigris.org. Both are free. First is the server side software, the heart and soul of the version control system. Second is the client side GUI interface. Nothing too fancy, they just work. Also make sure to backup the SVN repository regularly. Other choices are also available, such as CVS, etc. You can also set TortoiseSVN to use any file comparison tools, in my case, I set it to use Beyond Compare.

Another neat tool we started to use recently is the UniversalIndentGUI, http://universalindent.sourceforge.net. This tool helps in formatting codes, by processing them per the formatting rules given. If you need to publish your code, whether publicly or just to your customers, this tool helps make everything looks consistent as though the codes were written by just one programmer. UniversalIndentGUI doesn’t solve all the consistency issues, like variable and function names. For that, your team need to have a coding style policy to follow in the first place. But for indentation, parenthesis, and other formatting related items, this tool takes the meaning of the word quality to another level.

Moving on to text editor. In all likelihood, your computer has the Notepad program that comes with Microsoft Windows, and you also have an IDE (Integrated Development Environment) installed. Your source code files are probably associated with the IDE. But there will be times when you just want to browse folders, and all you want to do is to quickly inspect a source file, both Notepad and IDE may not be a good solution. Notepad doesn’t highlight syntax, and IDE doesn’t load quickly. In this case, I use another text editor that can highlight syntax, better than Notepad, but also light-weight when compared to an IDE. The program I use is Notepad++, free and can be found at, http://notepad-plus.sourceforge.net. Many other options are also available, such as EditPlus, TextPad, etc.

Talking about editor, another good tool to have is a hex file viewer/editor. I use XVI32, http://www.chmaas.handshake.de/delphi/freeware/xvi32/xvi32.htm. Not everything you work with is in a text readable form, so something like the XVI32 is a must have.

Another good tool is TreeSize Free, http://www.jam-software.com/freeware/index.shtml. This tool helps you analyze the disk size allocation of files and folders. I typically use this tool to scan code repository before each public code release. It helps me to understand the file organization from the size perspective. I also tend to use it to look out for any unexpected files that may get introduced to the SVN repository unintentionally. This is helpful when the code distribution is large, and you want to keep the installer package size within a reasonable level.

When it comes to documenting APIs, there was a time when we documented our function APIs by writing them out again manually in a separate document, be it a Microsoft Word or Acrobat PDF. This was an insane way of doing things. Mistakes can happen left and right. Synchronization between the actual code and help file was also very hard to keep up with. When an actual function API changed, we would have to remember to update the documentation too. Typographical errors were also very common, which made the document harder to understand for the end readers. The whole process of tracking and editing was also very time consuming. Fortunately, those were the old days. Now we use Doc-O-Matic, http://www.doc-o-matic.com. The tool scans source codes for comments and function headers and use them to outputs documentation help file in various formats automatically. Doc-O-Matic is not free, but a great investment that helps save countless hours of manual work, which makes it a cheaper choice in the long run. A free alternative is Doxygen, http://www.stack.nl/~dimitri/doxygen. If you are not using a help authoring tool, you should start, today.

Lastly for packaging an installer, we use Nullsoft Scriptable Install System (NSIS), http://nsis.sourceforge.net, which is free. For a programmer, learning how to use NSIS should be easy, as you will be writing a script. Many functions and templates are provided. We use the Modern UI template. You will see this template once you have installed NSIS. I’d highly recommend this template and I believe most NSIS users use this template also. To learn the in and out of the Modern UI template, start by reading here: http://nsis.sourceforge.net/Docs/Modern%20UI/Readme.html.

The list above shows just some of the tools we have used within our work environment, some maybe applicable to you, some may not. At some points in the past, we never used to use them either, but we observed where we could improve our productivity and efficiency, and started introducing these tools into our work culture. You could do the same. If the tool doesn’t exist, consider in building one.

Tags: , , , ,

 
0

Sensor Degradation

Posted by Cassie on Nov 3, 2009 in Uncategorized

It’s a snowy night, and you’re about to use the ATM outside your local grocery store that’s been there for years. You enter in your access code, and notice only 2 of the 4 entries are reflected on the display.

You clear the entry, and strike each number on the monitor again. Again the entry seems off.

Now your card is eaten up in that darned machine.

The touch screen doesn’t work.

What is really happening is that the touch screen isn’t working as well as it used to. Several factors can lead to sensor degradation. This sensor degradation, when not accounted for, can push the operating specifications of your touch controller and sensor pair out of functioning range.

Resistive touch panels are made of two sheets of conductive material. This conductive material needs to be uniformly coated on both sides. When you press a resistive panel, one side smushes into the other side. The bending of the flexible layer, referred to as the “flex” layer which is often made of polyester, into the glass or plastic layer, the “stable” layer, is what makes the resistive touch solution work and move your cursor. The conductive coating afixed to the flex layer is bent and stretched when the polyester layer comes in contact with a user’s finger or stylus. The metallic conductive coating does not have the same flexible properties as this polyester layer, and can stretch and crack with repeated use.

The humidity and the temperature of the environment also affects the wear and tear seen by the resistive panel. The air trapped inside the resistive panel is maintained by adding a layer, often called spacer dots, between the flex and the stable. Typically, this is maintained when the environment remains static. When the temperature rises or falls dramatically, the air within the sensor will expand or contract, stretching the polyester layer again. Thusly, the uniform coating becomes less uniform, and the sensor’s electrical properties are again compromised. The resistance of the panel will increase as the coating cracks, and the capacitance between the two conductive layers will increase as the polyester relaxes.”

While there are coatings and heaters and special manufacturing precautions to add to the longevity of the sensor, the sensor will eventually succumb to wear and tear and stop functioning. It’s up to the touch controller to be designed with a wide window of operation so that it will continue to function for as long as possible.

Tags:

 
0

Parsing serial text based commands

Posted by Carol on Oct 27, 2009 in Uncategorized

One of the fun tasks I have at work is creating fun lab projects for teaching classes.  In this case, the class was on basic embedded programming and the object was to show how serial input command strings are parsed into their basic components.  My pseudo project was a coffee maker, and the command set was relatively simple;

 

T 12:00                        sets the real time clock to 12:00

A 1:00                         sets the start time for the coffee maker to 1:00

M                                             turns on the timer

m                                             turns off the timer

?                                                          returns the time, start time, and current temperature of the coffee

 

Now, while the command set looks relatively simple, I also had to make it reasonably fool proof to use as well.  So;

1.                  I had to be able to accept both upper and lower case for the time and alarm commands.

2.                  I had to accept both single and double digit input for the hours.

3.                  I had to accept both a ‘ ‘ or a ‘:’ as a data delimiter.

4.                  And, I had to accept a cr as a delimiter and the termination of the command string.

 

So, I started out by creating a set a of variables to hold the parsed data;

 

A CHAR to hold the command character.  Note: mt_char is a default character.

      cmd_char   = mt_char;

 

And a 4 data variables for the individual nibbles of the hours and minutes

      data_var1a = 0;

      data_var2a = 0;

      data_var1b = 0;

      data_var2b = 0;

 

I then created an init routine to preset the variables to their default values.  Note, I use this both at startup, and after I decode the commands, to preset the variables for the next command string.

 

/******************************************************************************

* Function: void pars_init(void)

*

* Overview: This function configures the parser for operation

*

* Input:    none

*

* Output:   none

*

******************************************************************************/

void pars_init(void)

{

       cmd_char   = mt_char;

       data_var1a = 0;

       data_var2a = 0;

       data_var1b = 0;

       data_var2b = 0;

       mode       = cmd;

       pars_done  = 0;

       pars_falt  = 0;

}     

 

Note: resetting the variables to zero also provides any leading zeros required for single digit entries.

 

Next, I created my parser routine in two halves; the first which accepts the individual characters from the serial input and parses the data into blocks, and a second which executes the actual command.

 

The first section is implemented as a statemachine with 4 states, CMD for command, VAR1 for the first data variables, VAR2 for the second data variable, and DEFAULT which is a general error handler. 

 

In the CMD state, any character that is not a number or a delimiter is stored in the cmd_char variable.  If the character is a ‘ ‘, then the statemachine is advanced to the VAR1 state.  If the character is a cr, then the parser is done and the command can be decoded by the second half of the routine.  If any other character is detected than a pars_falt is set indicating an invalid command.

 

In the VAR1 state, any number is stored in the data_var1a, after the contents of data_var1a has been shifted into data_var1b.  This shift register arrangement allows us to either enter 1 or 2 values because both variables were cleared prior to the start of the command, leaving a leading zero for any single value entry.  If the character is a ‘:’, then the statemachine advances to the state VAR2 for a second value entry.  If the character is a cr, then the parser is done and the command can be decoded by the second half of the routine.  If any other character is detected than a pars_falt is set indicating an invalid command.

 

The VAR2 state operates nearly identically to VAR1, with the exception that the only delimiter accepted is the cr to terminate the command.

 

The only function of the default state is to set the fault flag so the second half of the routine can reset the statemachine to its default condition.

 

When the first half of the function is complete, and the  pars_done variable is set, then the 5 data variables (            cmd_char, data_var1a, data_var2a, data_var1b, & data_var2b) should have legal values in them, either from data received from the serial port, or default data loaded during the initialization function.

 

/******************************************************************************

* Function: void parser(void)

*

* Overview: This function disassembles serial command strings

*

* Input:    none

*

* Output:   values

*

******************************************************************************/

void parser(void)

{

       switch(mode)

       {

              Case cmd:     if (((hold >= ‘a’)&(hold <= ‘z’)) | ((hold >= ‘A’)&(hold <= ‘Z’)) | (hold == ‘?’))

                                         {

                                                cmd_char = hold;                         // a-z or A-Z or ? detected store as command

                                          }     

                     else if (hold == ‘ ‘)

                     {

                           mode = var1;                             // ‘ ‘ delimiter detected goto next field of data

                     }

                     else if (hold == CR)

                     {

                           pars_done  = 1;                          // CR detected terminate parser and decode command

                     }

                     else

                     {     

                           pars_falt  = 1;                          // no clue send a ? and restart

                     }

                     break;

              case var1:    if ((hold >= ‘0′) && (hold <= ‘9′))

                                         {

                                                data_var1b = data_var1a;   // 0-9 detected store as first data

                                                data_var1a = hold – ‘0′;

                                         }     

                                         else if (hold == ‘:’)

                                          {

                                                 mode = var2;                             // ‘:’ delimiter detected goto next field of data

                                          }

                                          else if (hold == CR)

                                          {

                                                pars_done  = 1;                                 // CR detected terminate parser and decode command

                                          }

                                         else

                                          {     

                                                pars_falt  = 1;                                 // no clue send a ? and restart

                                         }     

                                         break;

              case var2:    if ((hold >= ‘0′) && (hold <= ‘9′))

                                         {     

                                                data_var2b = data_var2a;          // 0-9 detected store as second data

                                                data_var2a = hold – ‘0′;

                                         }

                                         else if (hold == CR)

                                         {

                                                pars_done  = 1;                                 // CR detected terminate parser and decode command

                                         }

                                         else

                                          {     

                                                pars_falt  = 1;                                 // no clue send a ? and restart

                                          }     

                                          break;

              default:             pars_falt = 1;                                                // definitely lost, send a ?

                                         break;

       }                         

 

Once the data is parsed into its separate elements, it is a simple matter to decode the command and routine the new data into the appropriate variables.  In this case; rtc_hours, rtc_mins, alrm_hours, alrm_min, & alrm_on.  Based on the value in cmd_char, a simple switch statement is all that is needed to routine the incoming data to the appropriate variables.  Once the command decode is complete, then the routine is reset by calling the initialization routine to clear the variables and set them to their default values.  In the event that their was a communications fault during the parse or decode operation, then the data is discarded and the system is reset using the initialization routine.

 

       if (pars_done == 1)                                                                // if CR detected, then decode the command

       {

              switch(cmd_char)

              {

                     case ‘T’:                                                                          // time command uses both data blocks

                     case ‘t’:     rtc_hours = (data_var1b * 10) + data_var1a;

                                                rtc_mins  = (data_var2b * 10) + data_var2a;

                                                break;

                     case ‘A’:                                                                          // alarm set command uses both data blocks

                     case ‘a’:     alrm_hours = (data_var1b * 10) + data_var1a;

                                                alrm_mins  = (data_var2b * 10) + data_var2a;

                                                break;

                     case ‘M’:     alarm_on = 1;

                                                break;

                     case ‘m’:     alarm_on = 0;

                                                break;

                     case ‘?’:     send_all_data();                                // ? sends the time, alarm, and temperature

                                                break;

              }     

              pars_init();

       }     

       if (pars_falt == 1)

       {

              Tx_send(’?');                                                                     // send ‘huh?’ message to user

              Tx_save(CR);

              Tx_save(LF);

              pars_init();

       }     

}

Tags: ,

 
0

Converting between binary and decimal in assembly

Posted by Keith on Oct 22, 2009 in Uncategorized

One of the interesting challenges in working in assembly, versus C, is converting between BCD and binary. We all know that processors work in binary and users work in C, right? The problem is, even thought some processors include BCD math capabilities, things like multiplication, division, and all the system timers, work in binary.

So, one of the long standing problems, is how do we efficiently convert between base 2 and base 10. Well, a couple of years ago, I was faced with this problem, and I came up with a fairly efficient conversion algorithm that works well in both directions.

The routines are based on the same basic principal as a multiply routine. For example, let’s convert an 8-bit binary number to BCD.

8-bit binary value 10110101

First, we build up a constant table for each bit location;

0 0 1

0 0 2

0 0 4

0 0 8

0 1 6

0 3 2

0 6 4

1 2 8

Then we create a set of BCD output variables and clear them

BCD100 BCD10 BCD1

Next, we shift through the binary value, and for every 1, we add the corresponding value from the table, using BCD addition;

8-bit binary value 10110101

0 0 1

0 0 4

0 1 6

0 3 2

+ 1 2 8

—————————————

1 8 1

To go in the other direction, we just use a binary array of constants, and add using binary addition

BCD value 181

Binary constants

00000001 1

00000010 2

00000100 4

00001000 8

00001010 10

00010100 20

00101000 40

01010000 80

01100100 100

11001000 200

And the conversion looks like this;

BCD value 181

01100100 100

01010000 80

+ 00000001 1

———————————-

10110101

Of course, this technique can be expanded to any number of bits; all you need to do is expand the constant table to include all the bit values. Attached to the end of this blog are listings for both binary to decimal and decimal to binary for the PIC16FXXX family of parts;

;************************************************************************

; Converts a 5 digit BCD to 16-bit number in H_byte:L_byte

; Limitation: 5-digit bcd must be less than 2^17 (= 65536) in order

; to fit into the 16-bit result. Else result is remainder.

;

; R2H R2L R1H R1L R0H R0L

; - dig5 dig4 dig3 dig2 dig1

BCD5BIN16:

clrf H_byte

movf R2, W

andlw 0×0F

movwf L_byte

call mpy10a ; result = 10a+b

swapf R1, W

call mpy10b ; result = 10[10a+b]

movf R1, W

call mpy10b ; result = 10[10[10a+b]+c]

swapf R0, W

call mpy10b ; result = 10[10[10[10a+b]+c]+d]

movf R0, W

andlw 0×0F

addwf L_byte, F

btfsc STATUS, C

incf H_byte, F ; result = 10[10[10[10a+b]+c]+d]+e

return ; BCD to binary conversion done

mpy10b:

andlw 0×0F

addwf L_byte, F

btfsc STATUS, C

incf H_byte, F

mpy10a:

bcf STATUS, C ; multiply by 2

rlf L_byte, W

movwf L_temp

rlf H_byte, W ; (H_temp,L_H_temp) = 2*N

movwf H_temp

bcf STATUS, C ; multiply by 2

rlf L_byte, F

rlf H_byte, F

bcf STATUS, C ; multiply by 2

rlf L_byte, F

rlf H_byte, F

bcf STATUS, C ; multiply by 2

rlf L_byte, F

rlf H_byte, F ; (H_byte,L_byte) = 8*N

movf L_temp, W

addwf L_byte, F

btfsc STATUS, C

incf H_byte, F

movf H_temp, W

addwf H_byte, F

return ; (H_byte,L_byte) = 10*N

;*********************************************************************

;———————————————————————

; Bin16BCD

; Converts 16-bit binary number (H_byte:L_byte) into a 5 digit

; BCD number in 5 nibbles of registers R2, R1, R0 as shown.

;

; R2H R2L R1H R1L R0H R0L

; - dig5 dig4 dig3 dig2 dig1

;———————————————————————

Bin16BCD:

bcf STATUS,C ; clear the carry bit in STATUS

movlw .16

movwf temp+1

clrf R0

clrf R1

clrf R2

b16b_loop16:

rlf L_byte, F

rlf H_byte, F

rlf R0, F

rlf R1, F

rlf R2, F

decfsz temp+1, F

goto adjDEC

return

adjDEC:

movlw R0

movwf FSR

call adjBCD

movlw R1

movwf FSR

call adjBCD

movlw R2

movwf FSR

call adjBCD

goto b16b_loop16

adjBCD:

movlw 0×03

addwf INDF,W

movwf temp

btfsc temp,3 ; test if result > 7

movwf INDF

movlw 0×30

addwf INDF,W

movwf temp

btfsc temp,7 ; test if result > 7

movwf INDF ; save as MSD

return

Tags: ,

 
0

Capacitive Touch Algorithm Tuning for Thick Overlays

Posted by Padmaraja on Oct 20, 2009 in Capacitive Touch

Often the capacitive touch applications need thick overlay to be used over the capacitive touch pads to make the system mechanically robust. In addition to that, for aesthetic reasons, the overlay may be curved. This poses a serious issue of reducing the touch sensitivity. The curvature on the overlay distorts the sample reading from the buttons. Also it gives a variation in reading from button to button. To overcome these issues, the capacitive touch algorithm needs some tuning.      

 

When thick overlay of plastic or glass is used, the sensitivity goes down significantly. As you know, the human touch produces a basic capacitor, with finger and the touch pad being the electrodes and the overlay material is the dielectric material separating the plates. Because the thickness of the dielectric material increased(the overlay), the capacitance shift produced by touch reduces, thus reducing the sensitivity. Because of this, the signal to noise ratio reduces further down.

To overcome this, a slow moving average algorithm is used. First, the capacitive sensing module, such as Charge Time Measurement unit(CTMU) or Capacitive Sensing Module(CSM), is sampled 16 to 64 times(N Samples) every fixed interval. These N samples are accumulated and used as the current running sample. The averaging algorithm takes the current sample and takes a fraction of it and adds to the running average. The running average is not updated until 20 or more samples of slow moving average. By doing this the average changes very slow and the slight shift of the current sample allows to detect the touch.

Because of the low sensitivity, the difference between the current sample and the average data could be less than 1%. Each channel needs tuning on the number of samples for slow moving average to suit the touch key size and key characteristics.

 
0

24-hr Microchip Technology giveaway for Halloween

Posted by Carol on Oct 8, 2009 in Uncategorized

Makezine

 
0

Interesting Webcast about microcontroller in Human Interface

Posted by Yann on Oct 5, 2009 in Capacitive Touch, Displays, General

Technical Editor Robert Cravotta explores processor and software-processing architectures and the impact they have on system and software development. Relevant architectures include microprocessors, microcontrollers, digital signal processors (DSPs), multiprocessor architectures, processor fabrics, coprocessors, and accelerators, plus embedded cores in FPGAs, SOCs, and ASICs.

EDN Webcast

Copyright © 2010 Notes from the Lab All rights reserved. Theme by Laptop Geek.