Forum: Compiler & IDEs Kapazitiver Sensor mit ATTiny13 - Bascom > C


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Дмитрий Л. (gottdrak99)


Lesenswert?

Hallo zusammen,

ich habe folgende Seite http://www.elektronik-labor.de/AVR/Touch.html 
als Referenz genutzt, um einen kapazitiven Sensor für ATTiny13 
nachzubauen. Da meine Bascom Kenntnisse eher bescheiden sind, habe ich 
versucht die paar Zeilen ins C zu übersetzen. Leider will meine LED mit 
C Code nicht leuchten.
Mit Bascom funktioniert dies einwandfrei (auch mit 9.6 Mhz anstatt mit 
1.2 Mhz)

// Kapazitiver Touch-Sensor
// 1,5 nF zwischen B3 und B4
// Sensorplatte an B4
// LED mit 1 k an B1

#define F_CPU 9600000 // 9.6 MHz

#include <avr/io.h>
#include <util/delay.h>
#include <stdint.h>

int main(void)
{
  uint16_t i, d;

  DDRB |= (1 << PB1);

  while (1)
  {
    d = 1;

    for (i = 1; i < 1500; i++)
    {
      DDRB &= ~(1 << PB3); // B3 hochohmig
      PORTB |= (1 << PB4); // B4 high
      DDRB |= (1 << PB4); // B4 niederohmig

      if (!(PINB & (1 << PB3)))
        break;

      DDRB &= ~(1 << PB4); // B4 hochohmig
      PORTB &= ~(1 << PB4); // ohne Pullup
      DDRB |= (1 << PB3); // B3 high

      d++;
    }

    PORTB &= ~(1 << PB3);
    PORTB &= ~(1 << PB4);
    DDRB |= (1 << PB3);
    DDRB |= (1 << PB4);

    if (d < 5)
      PORTB |= (1 << PB1);
    else
      PORTB &= ~(1 << PB1);

    _delay_ms(50);
  }
}

von Karl H. (kbuchegg) (Moderator)


Lesenswert?

So wie ich das gesehen habe, hast du das BASCOM Programm korrekt 
umgesetzt.
Nur eines:
Da ich erwarten würde, dass das C Programm schneller arbeitet als 
BASCOM, müsstest du doch die Abfrage

    if (d < 5)

erhöhen und nicht erniedrigen. Das C Programm würde d in derselben Zeit 
(die Zeit ist ja durch den Kondensator vorgegeben) potentiell höher 
zählen als BASCOM

aus Bascoms   d < 30
würde ich mal d < 40 (50, 60, 70) machen.

von Дмитрий Л. (gottdrak99)


Lesenswert?

Ich habe festgestellt dass die Variable d am Ende der Prüfung immer 2 
ist.

Sprich mit

    if (d == 2)
      PORTB |= (1 << PB1);
    else
      PORTB &= ~(1 << PB1);

leuchtet die LED dauerhaft.

Das bedeutet er steigt bereits beim zweiten Durchlauf aus.
Ein größerer Kondensator bringt auch kein Licht ins Dunkle...

von Peter D. (peda)


Lesenswert?


von Дмитрий Л. (gottdrak99)


Lesenswert?

Danke für die Unterstützung. Es funktioniert soweit sehr zuverlässig.
Sollte jemand ein ATTiny13 als Touch nutzen, stelle ich vorsichtshalber 
mein C Code hier rein.

Wenn die Initialisierung OK ist, leuchtet die LED für 1 Sekunde auf.
1
#define F_CPU 9600000 // 9.6 MHz
2
3
#include <avr/io.h>
4
#include <util/atomic.h>
5
#include <stdint.h>
6
#include <util/delay.h>
7
8
#define SK_A0   (1 << 3)
9
#define SK_B0   (1 << 4)
10
11
#define SK_A012 (SK_A0)
12
#define SK_B012 (SK_B0)
13
14
#define OBSERVATIONAL_ERROR   3
15
16
uint16_t keys[1];
17
18
void read_senskey(void)
19
{
20
  uint16_t i = 2000;
21
  uint8_t a, b, x, y;
22
23
  ATOMIC_BLOCK(ATOMIC_FORCEON)
24
  {
25
    a = DDRB  & ~(SK_A012 | SK_B012);
26
    b = PORTB & ~(SK_A012 | SK_B012);
27
    y = SK_B012;                  // input mask
28
    
29
    do
30
    {
31
      DDRB = a;                   // tristate
32
      PORTB = b | SK_B012;
33
      DDRB = a | SK_B012;         // Bx = strong high
34
      DDRB = a;                   // tristate
35
      PORTB = b;
36
      DDRB = a | SK_A012;         // Ax = strong low
37
38
      if( --i == 0 )              // timeout
39
        break;
40
41
      x = y & PINB;               // not immediately after set DDRB !!!
42
      if(x)
43
        if( x & SK_B0 )
44
          keys[0] = i;
45
46
      y ^= x;                     // clear processed input
47
    } while(y);                   // all inputs done
48
49
    DDRB = a | SK_A012 | SK_B012; // discharge
50
  }
51
}
52
53
int main(void)
54
{
55
  DDRB |= (1 << PB1); // Sensor LED
56
57
  // init default value
58
  uint16_t initvalue;
59
  do
60
  {
61
    initvalue = keys[0];
62
    for (int j = 1; j < 255; j++)
63
      read_senskey();
64
  } while (initvalue != keys[0]);
65
66
  // init ok
67
  PORTB |= (1 << PB1);
68
  _delay_ms(1000);
69
  PORTB &= ~(1 << PB1);
70
71
  while (1)
72
  {
73
    read_senskey();
74
75
    if (initvalue - OBSERVATIONAL_ERROR < keys[0])
76
      PORTB |= (1 << PB1);
77
    
78
    if (initvalue + OBSERVATIONAL_ERROR > keys[0])
79
      PORTB &= ~(1 << PB1);
80
81
    _delay_ms(150);
82
  }
83
}

von Thomas S. (tstag)


Lesenswert?

TOP, vielen Dank! Hab ewig rumgeschustert und nichts zustande gebracht 
bis ich endlich deinen Beitrag gefunden hab! Danke!

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]
  • [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.