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


von Andi (Gast)


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.

von AVerr (Gast)


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:
1
#include <avr/io.h>
2
#include <util/atomic.h>
3
4
#define MAX_CYCLE       2000
5
6
#define SENSKEY_A0      SBIT( PORTC, 0 )
7
#define SENSKEY_A0_DDR  SBIT( DDRC,  0 )
8
#define SENSKEY_B0      SBIT( PORTC, 1 )
9
#define SENSKEY_B0_DDR  SBIT( DDRC,  1 )
10
#define SENSKEY_B0_PIN  SBIT( PINC,  1 )
11
12
struct bits {
13
  uint8_t b0:1;
14
  uint8_t b1:1;
15
  uint8_t b2:1;
16
  uint8_t b3:1;
17
  uint8_t b4:1;
18
  uint8_t b5:1;
19
  uint8_t b6:1;
20
  uint8_t b7:1;
21
} __attribute__((__packed__));
22
23
#define SBIT_(port,pin) ((*(volatile struct bits*)&port).b##pin)
24
#define  SBIT(x,y)  SBIT_(x,y)
25
26
uint16_t read_senskey( void )
27
{
28
  uint16_t i = MAX_CYCLE + 1;
29
30
  SENSKEY_A0 = 0;
31
  SENSKEY_A0_DDR = 1;
32
  SENSKEY_B0 = 0;
33
  SENSKEY_B0_DDR = 1;           // discharge cap
34
35
  ATOMIC_BLOCK(ATOMIC_FORCEON){
36
    do{
37
      SENSKEY_A0_DDR = 0;       // A0 = tristate
38
      SENSKEY_B0 = 1;           // B0 = weak high
39
      SENSKEY_B0_DDR = 1;       // B0 = strong high
40
      SENSKEY_B0_DDR = 0;       // B0 = weak high
41
      SENSKEY_B0 = 0;           // B0 = tristate
42
      SENSKEY_A0_DDR = 1;       // A0 = strong low
43
      if( --i == 0 )
44
        break;                          // timeout
45
    }while( SENSKEY_B0_PIN == 0 );      // until charged
46
  }
47
  SENSKEY_B0_DDR = 1;           // discharge cap
48
  return MAX_CYCLE - i;         // big value = key touched or timeout
49
}
50
51
int main()
52
{
53
  DDRD = (1<<PD5);
54
55
  while(1)
56
  {
57
    if(read_senskey() >= 1500)
58
    {
59
      PORTD &= ~(1<<PD5);
60
    }
61
    else
62
    {
63
      PORTD |= (1<<PD5);
64
    }
65
  }
66
67
  return 0;
68
}

in der while Schleife, bei
1
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.

von AVerr (Gast)


Lesenswert?

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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.