INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.

Antwort schreiben 
 
Themabewertung:
  • 0 Bewertungen - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Klatsch-Sensor auf Attiny13A für verschiedene Rythmen
13.06.2020, 11:06 (Dieser Beitrag wurde zuletzt bearbeitet: 13.06.2020 11:20 von Vapalus.)
Beitrag #1
Klatsch-Sensor auf Attiny13A für verschiedene Rythmen
An dieser Stelle eine Vorwarnung:
In dem Projekt wird - ohne Verstärker, ohne Verstand - ein Elektretmikrofon mit einem Widerstand an einen Attiny13A angeschlossen.
Der Schaltplan sieht in Etwa so aus:
   

Ursprünglich war nur geplant, dass der Sensor auf 3 mal Klatschen reagiert.
Jedoch habe ich zwischendrin husten müssen, was den Sensor angeschalten hat...
Und mich auf die Idee brachte, eine Art "Rythmussensor" daraus zu machen.
Man muss also in einem bestimmten Rythmus klatschen, damit er funktioniert.

Insgesamt besteht der Code aus 3 Teilen:
Der Deklaration des Klatschrythmus, dem Timerinterrupt und dem Loop, der das Mikrofon abfängt.

Wie man sehen kann, kann man unterschiedliche Rythmen an unterschiedliche Pins binden.
Gleichzeitig, wohlgemerkt - man kann also einen Rythmus für die blaue, und einen anderen Rythmus für eine grüne LED verwenden, und der Attiny kann sie unterscheiden.
Dazu reicht es, den Rythmus als differenz zwischen den einzelnen Klatschevents zu definieren und mit
"ClappingTune tune(pin, rythmus, länge);"
einzubinden.

Code:
#include <avr/io.h>
#include <avr/interrupt.h>

#define LED_PIN_GREEN 1
#define LED_PIN_BLUE 0
#define INPUT_PIN 3
#define CLAP_SPIKE 3
#define CLAP_ERROR_TOLERANCE 20

byte noise = 0;
byte lastTimeNoise = 0;
byte iCurrentADCVal = 0;
byte secondsSinceLastClap = 0;
//byte currentPos = 255;
//byte value = 0;

//TIMING_LENGTH is a necessity atm due to my poor coding skills
#define TIMING_LENGTH_ONE 6
const byte tune_one[TIMING_LENGTH_ONE] = {
                  40,//400 ms between first and second clap
                  20, //200 between second and third
                  20, //and so on
                  40,
                  70,
                  40
                  };
//Jingle bells clap:
#define TIMING_LENGTH_TWO 10
byte tune_two[TIMING_LENGTH_TWO] = {
                  30, //jing
                  30, //le
                  70, //bomb
                  30, //jing
                  30, //le
                  70, //bomb
                  30, //jing
                  30, //le
                  50, //all
                  20  //my ---
                  };

class ClappingTune{
  public:
  byte pos;
  byte pin;
  byte* tune;
  byte tuneLength;
  byte toggleValue;
  //////////////////////////////////////////////
  ClappingTune(byte pinToUse, byte* tuneToUse, byte tuneLengthToUse){
    pin = pinToUse;
    tune = tuneToUse;
    tuneLength = tuneLengthToUse;
    pos = 255;
    toggleValue = 0;
  }
  //////////////////////////////////////////////
  void onClap(byte secondsSinceLastClap){
    if (pos == 255){
      pos = 0;
    }
    else{
      if (abs(secondsSinceLastClap - tune[pos])< CLAP_ERROR_TOLERANCE){ //If you aren't smart enough for clapping in tact, have some error tolerance
        digitalWrite(pin,!toggleValue);
        pos++;//Increases "currentPos" by one. This is a useful comment. Please read it.
        if (pos == tuneLength){
          //It seems we are done. That means whatever you want to do when the clap-code is correct, you can do it here. I prefer to just set "value", take a shit and call it a day.
          toggleValue ^= 1;
          //Reset current pos, since it's a bad idea to read unknown Memory
          pos = 255;
        }
      }
      else{
        //Learn to clap, bro. Failure.
        pos = 255;
      }
    }
  }
  void afterClapCheck(){
    digitalWrite(pin,toggleValue);
  }
};

ClappingTune firstTune(LED_PIN_GREEN, tune_one, TIMING_LENGTH_ONE);
ClappingTune secondTune(LED_PIN_BLUE, tune_two, TIMING_LENGTH_TWO);




byte ignore = 0;

//Timer which is being called every 0.03 seconds. Please set your attiny to 9.3 MHz, else this thing won't work right.
ISR(TIM0_COMPA_vect)
{
  ignore ^= 1;
  if(ignore){
    return;
  }
  //Just prevents a "double detection"
  if (noise && !lastTimeNoise){
    //digitalWrite(LED_PIN_GREEN,!value); //Not really necessairy, just shows it detected a "clap" which makes it a more user-friendly piece of trash
    firstTune.onClap(secondsSinceLastClap);
    secondTune.onClap(secondsSinceLastClap);

    secondsSinceLastClap = 0;
    lastTimeNoise = 0;
  }
  else{
    //This is just here because I'm lazy. Makes the "clap" detection possible and also sets the value - at the same time. I'm a genius.
    firstTune.afterClapCheck();
    secondTune.afterClapCheck();
  }
  lastTimeNoise = 0;
  if (noise){
    noise = 0;
    lastTimeNoise = 1; //setting "lastTimeNoise" prevents any double-detection of the same clap, since a clap normally takes less than 0.03 seconds.
  }
  
  secondsSinceLastClap +=6; //add 0.06 seconds
  if (secondsSinceLastClap > 250){
    //Prevent integer overflow. Byte overflow. Whatever.
    secondsSinceLastClap = 250;
    //Reset the clapping position to prevent hilariarse situations.
    firstTune.pos = 255;
    secondTune.pos = 255;
  }
}

void adc_workaround_attiny13a (void)
{
    // Set the prescaler to clock/128 & enable ADC
    // Necessairy since it won't activate in "int main(void)" without using the "setup" makro/functionality/function
    ADCSRA |= (1 << ADPS1) | (1 << ADPS0) | (1 << ADEN);
}

int main(void)
{
  adc_workaround_attiny13a();

  //This doesn't work right with using "setup()" so I guess I'll just ignore any good coding practice and write this code slamming my head on the keyboard
  //I am using a timer to get the timing right. Who would have thought that using a timer helps with timing.
  TCCR0A |= _BV(WGM01); // set timer counter mode to CTC
  TCCR0B |= _BV(CS02)|_BV(CS00); // set prescaler to 1024 (CLK=9200000Hz/1024/256=35.1Hz, 0.03s)
  OCR0A = 255; // set Timer's counter max value
  TIMSK0 |= _BV(OCIE0A); // enable Timer CTC interrupt
  sei(); // enable global interrupts
  
  pinMode(LED_PIN_GREEN, OUTPUT); //Here comes the lazy
  pinMode(LED_PIN_BLUE, OUTPUT); //Here comes the lazy
  pinMode(INPUT_PIN, INPUT);  //Why should I use registers to set a fzcking pin, you fools

  while(1){
    //Getting the claps directly from the microphone
    byte iPreviousValue = iCurrentADCVal;
    iCurrentADCVal = analogRead(INPUT_PIN);
    if ((iPreviousValue-iCurrentADCVal)>CLAP_SPIKE){ //Guess what "Clap Spike" means, loser
      noise = 1;
    }
  };
}

Die Funktionsweise kann man auch im Video sehen.

http://www.youtube.com/watch?v=1hQT1DbPreo

Derzeit benutze ich ihn, um meine Lampe an und aus zu schalten.
Die Lampe steht direkt neben meinem Bett.
   
Meine Frau hat geplant, die Lampe inklusive mich aus dem Schlafzimmer zu werfen.

In der heutigen Zeit ist gesunder Menschenverstand so etwas Ähnliches wie eine Superkraft - aber keine nützliche.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
19.06.2020, 08:33
Beitrag #2
RE: Klatsch-Sensor auf Attiny13A für verschiedene Rythmen
(13.06.2020 11:06)Vapalus schrieb:  Derzeit benutze ich ihn, um meine Lampe an und aus zu schalten.
Die Lampe steht direkt neben meinem Bett.

Meine Frau hat geplant, die Lampe inklusive mich aus dem Schlafzimmer zu werfen.

Ehrlich, das kann ich nachvollziehen.

Ich benutze für meine Lampe einen Bewegungsmelder, der auf eine reduzierte Empfindlichkeit getrimmt wurde.
Dabei muss ich nicht noch weitere Personen wecken.

Gruß Dieter

I2C = weniger ist mehr: weniger Kabel, mehr Probleme. Cool
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
19.06.2020, 09:13 (Dieser Beitrag wurde zuletzt bearbeitet: 19.06.2020 09:15 von Vapalus.)
Beitrag #3
RE: Klatsch-Sensor auf Attiny13A für verschiedene Rythmen
Dafür habe ich eine Lampe unter dem Bett, die nur den Boden beleuchtet, aber nicht das Bett selbst.
Gut um sich rauszuschleichen, und bedient wird es über das Smarthome.

Sobald ich meine selbstgebaute Smartwatch endlich richtig zum Laufen kriege (da gibt es noch Verbindungsprobleme mit dem WLAN, scheint aber ein Problem mit der Fritzbox zu sein, das ich selbst wohl verursacht habe) kann ich sogar alles am Handgelenk an- und ausschalten.

Nein, da seit der Schwangerschaft meiner Frau das Kinderzimmer wegfällt ist jetzt meine Lötstation direkt neben dem Bett.
Gott sei Dank jetzt mit automatischer Abschaltfunktion Smile

In der heutigen Zeit ist gesunder Menschenverstand so etwas Ähnliches wie eine Superkraft - aber keine nützliche.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Möglicherweise verwandte Themen...
Thema: Verfasser Antworten: Ansichten: Letzter Beitrag
  Bodenfeuchte Sensor Norik 01 5 1.382 11.03.2020 17:16
Letzter Beitrag: Norik 01
  10-20 Volt Sensor am Arduino MEGA Nopody33 4 4.320 03.08.2015 10:57
Letzter Beitrag: Nopody33
Wink Pulse Sensor Amped ohne Processing Sandmannn 16 9.844 18.02.2015 17:05
Letzter Beitrag: Thorsten Pferdekämper
  433MHz Funk- Helligkeits- Sensor MaHa1976 5 5.854 30.12.2014 18:15
Letzter Beitrag: MaHa1976
  Temperaturschalter mit Relais und KTY-Sensor. Einsteiger94 1 4.342 17.10.2014 15:49
Letzter Beitrag: SkobyMobil

Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste