ATTiny85 - virtualwire und timerfreetone funktionieren nicht gleichzeitig

Hallo, ich bin gerade dabei, meine Türklingel mit 2 ATTiny85 und 433 MHz bis in den Garten zu erweitern. Das Schalten einer LED am Empfänger klappt auch. Sobald ich aber versuche, mit der TimerFreeTone-Library Töne abzuspielen, bekomme ich nur einen Dauerton.

Wenn ich den Code auskommentiere, der die virtualWire library nutzt, funktioniert die Melodie.

jremington:
Caution: ATTiny85 has only 2 timers, one (timer 0) usually used for millis() and one (timer 1) for PWM analog outputs. The VirtualWire library, when built for ATTiny85, takes over timer 0, which prevents use of millis() etc but does permit analog outputs.

Hängt es mit dem obigen Auszug aus der virtualWire lib zusammen, dass es nicht funktioniert, oder muss ich irgendeine Fuse setzen, damit der Timer 1 für PWM genutzt wird?

Für einen Tipp in die richtige Richtung wäre ich dankbar.

Hier noch mein Sketch für den Empfänger:

#include <VirtualWire.h>
#include <TimerFreeTone.h>

#define rxPin 4
#define ledPin 2
#define TONE_PIN 0

int melody[] = { 262, 294, 330, 349, 392, 392, 440, 440, 440, 440, 392, 440, 440, 440, 440, 392, 349, 349, 349, 349, 330, 330, 392, 392, 392, 392, 262 };
int duration[] = { 200, 200, 200, 200, 400, 400, 200, 200, 200, 200, 800, 200, 200, 200, 200, 800, 200, 200, 200, 200, 400, 400, 200, 200, 200, 200, 800 };

void setup() {
  pinMode(rxPin, INPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(TONE_PIN, OUTPUT);

  vw_set_ptt_inverted(true);
  vw_set_rx_pin(rxPin);
  vw_setup(100); // Bits per sec
  vw_rx_start();
}

void loop() {
  uint8_t buf[VW_MAX_MESSAGE_LEN];
  uint8_t buflen = VW_MAX_MESSAGE_LEN;

  if (vw_get_message(buf, &buflen)) // Non-blocking
  {
    if (buf[0] == '1' && buf[1] == '1')
    {
      digitalWrite(ledPin, HIGH);
      delay(8000);
      digitalWrite(ledPin, LOW);
      for (int thisNote = 0; thisNote < 27; thisNote++) { // Loop through the notes in the array.
        TimerFreeTone(TONE_PIN, melody[thisNote], duration[thisNote]); // Play thisNote for duration.
        delay(50); // Short delay between notes.
      }
      int thisNote = 0;
      digitalWrite(ledPin, HIGH);
      delay(8000);
    }
    else
    {
      digitalWrite(ledPin, LOW);
      delay(8000);
    }
  }
}

Wenn VirtualWire den Timer 0 benutzt, dann funktioniert millis() nicht mehr richtig. Und wenn TimerFreeTone keinen Timer sondern millis() für's Timing benutzt, kann das dann nicht mehr richtig funktionieren.

Als Workaround kannst Du ausprobieren, ob millis() noch irgendwelche Werte liefert, die wenigstens proportional zur vergangenen Zeit sind, nur eben keine echten Millisekunden. Wenn das der Fall ist, könntest Du die Werte für die die Melodie (Tonhöhe und Dauer) an dieses geänderte Timing anpassen.

delay() läuft auch über Timer0

Hallo,
hast du schon mal andere Pins getestet ?

Ich habe z.B. den ATtiny85 mit einem 433 MHz Empfänger am Pin PB2 (physikalisch 7) laufen.

Und warum nimmst du nur 100 Bps ?
das geht problemlos bis 2000 Bps.
Und die Zeile "vw_set_ptt_inverted(true);" kannst du löschen, die wird nicht benötigt.

Alternative:
2. ATtiny einsetzen.

Danke für das Feedback. Andere Pins habe ich schon getestet, ohne Erfolg.

Ich werde jetzt einen zweiten ATTiny einsetzen und damit den eigentlichen Empfangsteil und virtual Wire vom Rest trennen.

ra-ma:
Danke für das Feedback. Andere Pins habe ich schon getestet, ohne Erfolg.

Ich werde jetzt einen zweiten ATTiny einsetzen und damit den eigentlichen Empfangsteil und virtual Wire vom Rest trennen.

Was mir grad noch einfällt:
Hast du mal RCSwitch getestet, die ist normal besser für Schaltvorgänge.
Wäre doch noch ein Versuch wert.