mikrocontroller.net

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


Autor: Дмитрий Л. (gottdrak99)
Datum:

Bewertung
0 lesenswert
nicht 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);
  }
}

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Дмитрий Л. (gottdrak99)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Дмитрий Л. (gottdrak99)
Datum:

Bewertung
0 lesenswert
nicht 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.
#define F_CPU 9600000 // 9.6 MHz

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

#define SK_A0   (1 << 3)
#define SK_B0   (1 << 4)

#define SK_A012 (SK_A0)
#define SK_B012 (SK_B0)

#define OBSERVATIONAL_ERROR   3

uint16_t keys[1];

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

  ATOMIC_BLOCK(ATOMIC_FORCEON)
  {
    a = DDRB  & ~(SK_A012 | SK_B012);
    b = PORTB & ~(SK_A012 | SK_B012);
    y = SK_B012;                  // input mask
    
    do
    {
      DDRB = a;                   // tristate
      PORTB = b | SK_B012;
      DDRB = a | SK_B012;         // Bx = strong high
      DDRB = a;                   // tristate
      PORTB = b;
      DDRB = a | SK_A012;         // Ax = strong low

      if( --i == 0 )              // timeout
        break;

      x = y & PINB;               // not immediately after set DDRB !!!
      if(x)
        if( x & SK_B0 )
          keys[0] = i;

      y ^= x;                     // clear processed input
    } while(y);                   // all inputs done

    DDRB = a | SK_A012 | SK_B012; // discharge
  }
}

int main(void)
{
  DDRB |= (1 << PB1); // Sensor LED

  // init default value
  uint16_t initvalue;
  do
  {
    initvalue = keys[0];
    for (int j = 1; j < 255; j++)
      read_senskey();
  } while (initvalue != keys[0]);

  // init ok
  PORTB |= (1 << PB1);
  _delay_ms(1000);
  PORTB &= ~(1 << PB1);

  while (1)
  {
    read_senskey();

    if (initvalue - OBSERVATIONAL_ERROR < keys[0])
      PORTB |= (1 << PB1);
    
    if (initvalue + OBSERVATIONAL_ERROR > keys[0])
      PORTB &= ~(1 << PB1);

    _delay_ms(150);
  }
}

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.