Can anyone explain this arduino code, and help me figure out how to do something similar in ASF?

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

Hi guys,

I wasn't sure I should post this in AVR or in here because this is AVR code I'd like to port to ASF.

 

Today I was reading about "Disney Touche" and how with a fairly simple circuit is used to detect various touches in a variety of different materials, and then found this Arduino proof of concept:

https://github.com/Illutron/AdvancedTouchSensing/blob/master/Arduino_sensing/Arduino_sensing.ino

 

The code itself is quite short, but I find it hard to follow.

 

This part is particular is not clear:

 

    CLR(TCCR1B,0);          //-Stop generator
    TCNT1=0;                //-Reload new frequency
    ICR1=d;                 // |
    OCR1A=d/2;              //-+
    SET(TCCR1B,0);          //-Restart generator

 

I also found someone else's "simplified" variation of it elsewhere:

 

#define steps 128

float values[steps];
float alpha;
int maxPos, maxVal;

void setup ()
{
  pinMode (9, OUTPUT); 
  TCCR1A = 0;
  TCCR1B = 0;
  TCCR1A |= (1 << COM1A0);        // Toggle OC1A on Compare Match.
  TCCR1B |= (1 << WGM12);         // CTC mode
  Serial.begin(9600);
}

void loop () {
  if (Serial.available()) {
    alpha = (float)Serial.read() / 255.0f;
  }
  maxPos = 0;
  maxVal = 0;
  for (int i = 0; i < steps; i++) {
    TCCR1B &= 0xFE;                       // turns off timer
    TCNT1 = 0;                            // resets timer counter register
    OCR1A = i;                            // sets new frequency step
    TCCR1B |= 0x01;                       // turns on timer
    float curVal = analogRead(0);
    values[i] = values[i] * alpha + curVal * (1 - alpha);  // exponential moving avg
    if (values[i] > maxVal) {                              // finds the signal peak
      maxVal = values[i];
      maxPos = i;
    }
  }
  Serial.print(maxPos, DEC);
  Serial.print(" ");
  Serial.println(maxVal, DEC);
  delay(200);
}

 

Which helps a little but still leaves me a little confused.

I don't have a lot of low-level hardware experience and I'm trying to wrap my head around what it's doing.

 

The code is specifically for the Uno and it seems TCCR1B, OCR1A and TCNT1 are registers that belong to TIMER1, a 16bit timer for pins 9 and 10. This is likely forcing an interrupt of some sort? Is it trying to sample for different time periods in order to capture a range of frequencies?

I'd like to accomplish something similar on a SAMD09, but understanding what the Arduino code is doing would be a good starting place :)

 

Thanks,

John

 

Last Edited: Mon. Jan 20, 2020 - 01:31 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
  1. It's not really Arduino code.   More like bare metal AVR code.
  2. Using the AVR hardware timers directly.
  3. No interrupts are involved.
  4. It's not directly portable to SAMD09, because the SAM timers are completely different.  You'd be better off stepping back a bit and figuring out what it's doing a higher level, and writing that for SAMD/ASF from scratch.
  5. AFAICT, it's something like "output various frequencies (or PWM values?) on one pin, through an analog filter that includes a capacitive touch panel as part of its circuit, and then measure the analog voltage (which will depend on the capacitance."
  6. If you're using ASF, you can probably use the Atmel QTouch library to do similar things.   The SAD09 datasheet says it includes support for various touch capabilities, but I don't see any actual hardware support.
  7. (Atmel's QTouch library is proprietary.  You don't get to look at the actual source.  Sigh.)

 

You might want to look at the Adafruit FreeTouch library

 

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

Thanks for an honest response!

 

I appreciate everything you wrote. Clearly I don't know what's going on ;)

 

Huh, here I go trying to reinvent the wheel huh? I might just investigate using QTouch/FreeTouch. Thanks for that suggestion.

Also I notice the same thing as you, the D09 seems to mention supporting PTC, but no actual info in the datasheet. Further reading suggests the D10 is a bit of an upgrade that provides actual PTC/touch capabilities. I could be convinced to go with the the D10 over the D09 if this is the case.

 

 

Last Edited: Mon. Jan 20, 2020 - 12:17 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The basis is to detect the response based on different frequencies. The timer is used to generate a frequency on a port pin. The analog value is read from the circuitry averaged then printed. The frequency is increased. Rinse and repeat.

What do you want to achieve? Touch buttons - if so, use the atmel libraries. If you want weird things like the disney article, then try their technique.