www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Brauche Hilfe bei Touch Sensor Programm


Autor: Andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

bin blutiger Anfänger in Sachen Mikrocontroller und brauche bei dem 
Touch Sensor Programm etwas Hilfe:

Wollte das Programm von Peter Danneger mal testen 
Beitrag "Re: qtouch - sekt oder selters"
bekomm es aber irgendwie nicht zum laufen: Hab alle benötigten 
Komponenten besorgt:
33nF Kondensator welcher an Pin A0 und B0 angeschlossen wird
1kOhm Widerstand (muss der an A0 oder B0 angeschlossen werden
1 Elektrode (einfache Leiterplatte mit dem Draht zum Widerstand)

Das Programm hab ich nur um die Ansteuerung der LED erweitert (weiß 
leider nicht ob das korrekt ist)

Hier mal das Programm:

#include <avr\io.h>
#include <util\atomic.h>


#define SK_A0   (1<<5)
#define SK_B0   (1<<4)
#define SK_A1   (1<<2)
#define SK_B1   (1<<3)
#define SK_A2   (1<<0)
#define SK_B2   (1<<1)

#define SK_A012 (SK_A0 | SK_A1 | SK_A2)
#define SK_B012 (SK_B0 | SK_B1 | SK_B2)


#define MAX_CYCLE       2000


uint16_t keys[3];


void read_senskey( void )
{
  uint16_t i = MAX_CYCLE;
  uint8_t a, b, x, y;

  ATOMIC_BLOCK(ATOMIC_FORCEON){
    a = DDRA  & ~(SK_A012 | SK_B012);
    b = PORTA & ~(SK_A012 | SK_B012);
    y = SK_B012;                        // input mask
    do{
      DDRA = a;                         // tristate
      PORTA = b | SK_B012;
      DDRA = a | SK_B012;               // Bx = strong high
      DDRA = a;                         // tristate
      PORTA = b;
      DDRA = a | SK_A012;               // Ax = strong low
      if( --i == 0 )                    // timeout
        break;
      x = y & PINA;                     // not immediately after set 
DDRA !!!
      if( x ){
        if( x & SK_B0 )
          keys[0] = i;
        if( x & SK_B1 )
          keys[1] = i;
        if( x & SK_B2 )
          keys[2] = i;
      }
      y ^= x;                           // clear processed input
    }while( y );                        // all inputs done
    DDRA = a | SK_A012 | SK_B012;       // discharge
  }
}
int main (void)
{
if ( PINA & (1<<PINA0) )
{
PORTC = PORTC | 0x01;
}
}

Mal noch ne andere Frage muss die Elektrode mit GND verbunden werden?

Hab das Programm mal aufgespielt aber leider tut sich nichts. LED ist in 
Ordnung und auch richtig verbunden. Hab auch mal ein Multimeter an den 
Kondensator geklemmt, tut sich leider auch nichts.

Hoffe ihr könnt mir helfen, im Grunde genommen will ich nur eine Led 
über eine Touch Elektrode anschalten können.

Autor: AVerr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die funktion read_senskey lieferte irgendwann einmal einen Wert zurück 
... da hat das mit dem Copy-Paste bei dir wohl nicht ganz geklappt.

Hier mal meine Version, die lief:
#include <avr/io.h>
#include <util/atomic.h>

#define MAX_CYCLE       2000

#define SENSKEY_A0      SBIT( PORTC, 0 )
#define SENSKEY_A0_DDR  SBIT( DDRC,  0 )
#define SENSKEY_B0      SBIT( PORTC, 1 )
#define SENSKEY_B0_DDR  SBIT( DDRC,  1 )
#define SENSKEY_B0_PIN  SBIT( PINC,  1 )

struct bits {
  uint8_t b0:1;
  uint8_t b1:1;
  uint8_t b2:1;
  uint8_t b3:1;
  uint8_t b4:1;
  uint8_t b5:1;
  uint8_t b6:1;
  uint8_t b7:1;
} __attribute__((__packed__));

#define SBIT_(port,pin) ((*(volatile struct bits*)&port).b##pin)
#define  SBIT(x,y)  SBIT_(x,y)

uint16_t read_senskey( void )
{
  uint16_t i = MAX_CYCLE + 1;

  SENSKEY_A0 = 0;
  SENSKEY_A0_DDR = 1;
  SENSKEY_B0 = 0;
  SENSKEY_B0_DDR = 1;           // discharge cap

  ATOMIC_BLOCK(ATOMIC_FORCEON){
    do{
      SENSKEY_A0_DDR = 0;       // A0 = tristate
      SENSKEY_B0 = 1;           // B0 = weak high
      SENSKEY_B0_DDR = 1;       // B0 = strong high
      SENSKEY_B0_DDR = 0;       // B0 = weak high
      SENSKEY_B0 = 0;           // B0 = tristate
      SENSKEY_A0_DDR = 1;       // A0 = strong low
      if( --i == 0 )
        break;                          // timeout
    }while( SENSKEY_B0_PIN == 0 );      // until charged
  }
  SENSKEY_B0_DDR = 1;           // discharge cap
  return MAX_CYCLE - i;         // big value = key touched or timeout
}

int main()
{
  DDRD = (1<<PD5);

  while(1)
  {
    if(read_senskey() >= 1500)
    {
      PORTD &= ~(1<<PD5);
    }
    else
    {
      PORTD |= (1<<PD5);
    }
  }

  return 0;
}

in der while Schleife, bei
if(read_senskey() >= 1500)
gibt die 1500 an, ab welchem Wert das ganze als aus betrachtet wird. Je 
nach aufbau musst du da einen anderen Wert ausprobieren. Kannst dich von 
unten nach oben vortasten, bis du die richtige Schwelle findest.

Meine LED hing an PD5, du kannst das natürlich ändern.

Autor: AVerr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
PS: Der Kondensator hing zwischen PC0 und PC1, die Elektrode war über 
den R mit PC0 verbunden.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.