uxomm:
Oh, das sich die Emfänger gegenseitig stören können hatte ich bisher gar nicht so "auf dem Schrim". Aber das könnte einige Probleme erklären...
Und da kommen dann auch wieder Erinnerungen vom Amateurfunk-Kurs (lang, lang ist's her) an die Oberfläche
Naja, manchesmal sind "alte" Dinge doch wieder nützlich.
Diese Empfänger sind alles Pendelaudion, die haben einen Oszillator der nahe der Empfangsfrequenz schwingt und damit einen Empfänger in der Nähe stören kann.
Man sollte einen Mindestabstand von 1 Meter einhalten.
Aber selbst da habe ich noch Beeinflussungen festgestellt.
Hab grad schnell den Wikipedia-Artikel gelesen. Sehr aufschlussreich, erklärt eigentlich alles
Deshalb halte ich diese Empfänger auch für "fast" ungeeignet.
Dass sie in den Steckdosen doch noch recht brauchbar funktionieren, grenzt fast an ein Wunder.
@Chris72622
Hier mein verwendeter Sketch für den ATtiny85 (45)
/*
* Funksteckdosen-Sketch für Attiny85, Bootloader 8 MHz intern, arbeitet nur mit 8 MHz intern
*
* V1.0; 2.658 Byte, 21.01.2016
*
*
Belegung des Attiny85:
1 (SS)PB5 | \/ | Vcc 8
2 PB3 | | PB2 (SCK) 7
3 PB4 | | PB1 (MISO) 6
4 GND | | PB0 (MOSI) 5
*/
#include <RCSwitch.h> // http://code.google.com/p/rc-switch/
RCSwitch mySwitch = RCSwitch();
const int txDataPin = 4; // Ausgang Sender-Daten (IC-Pin 3)
const int txEinPin = 3; // Eingang Steckdosen EIN (IC-Pin 2)
const int txAusPin = 0; // Eingang Steckdosen AUS (IC-Pin 5)
const uint8_t MaxSenden = 3; // max. Anzahl der Aussendungen
const uint8_t MaxSteckdosen = 3; // max. Anzahl der vorhandenen Funk-Steckdosen
// Hier die Sendercodierung eintragen
long TXCode_ein[ ] = { 5261000, 5261001, 5261002 }; // Funksetckdosen einschalten
long TXCode_aus[ ] = { 5262000, 5262001, 5262002 }; // Funksetckdosen ausschalten
void setup() {
pinMode (txDataPin, OUTPUT); // Sender-Daten
pinMode (txEinPin, INPUT); // Eingang Steckdosen Einschalten
pinMode (txAusPin, INPUT); // Eingang Steckdosen Ausschalten
// Transmitter is connected to Attiny Pin PB3 <-- That is physical pin2
mySwitch.enableTransmit(txDataPin);
// Optional set pulse length.
mySwitch.setPulseLength(180);
// Optional set number of transmission repetitions.
mySwitch.setRepeatTransmit(10);
// Optional set protocol (default is 1, will work for most outlets)
// mySwitch.setProtocol(1);
}
void loop() {
if (digitalRead(txEinPin) == LOW) {
sendTX_On();
}
if (digitalRead(txAusPin) == LOW) {
sendTX_Off();
}
}
void sendTX_On() {
for (int i = 0; i < MaxSenden - 1; i++) {
for (int j = 0; j < MaxSteckdosen - 1; j++) {
mySwitch.send(TXCode_ein[j], 24);
}
}
}
void sendTX_Off() {
for (int i = 0; i < MaxSenden - 1; i++) {
for (int j = 0; j < MaxSteckdosen - 1; j++) {
mySwitch.send(TXCode_aus[j], 24);
}
}
}
Die Ansteuerung erfolgt direkt durch digitale Pins.
Die maximale Anzahl der Aussendungen und der Steckdosen kann konfiguriert werden.
HotSystems:
Quote from: uxomm
Und da kommen dann auch wieder Erinnerungen vom Amateurfunk-Kurs (lang, lang ist's her) an die Oberfläche
Und dann aufgegeben oder aktiv ?
In den späten Achzigern die Amateurfunkprüfung gemacht - inclusive Morsen - dann ein wenig beim lokalen Club aktiv gewesen (in den frühen Neunzigern), aber nie ein Rufzeichen beantragt (hauptsächlich aus finanziellen Gründen). Später dann mit anderen Dingen beschäftigt.
Aber: das erworbene Grundlagenwissen war mir immer wieder mal sehr nützlich!
Nehmen wir mal an, ich würde dem ATtiny nicht nur zwei "Zustände" übergeben wollen, sondern auf ihm einen Fifo-Puffer aufbauen wollen, der mit verschieden Schaltzuständen* gefüttert werden können soll.
Auf welche Art und Weise würdet Ihr dem ATtiny dann diese Daten bereitstellen? Seriell, oder?
Hat jmd. von Euch Software Serial auf nem ATtiny am laufen?
Hier ist Software Serial nicht aufgeführt und hier steht, dass im Fall einer seriellen Verbindung, die Daten auf einem ATtiny empfangen kann spezielle Vorkehrungen in Form einer speziellen Taktlibrary notwendig seien. Ich hab die Hoffnung, dass meine Quellen lediglich hoffnungslos veraltet sind und serielle Kommunikation mit einem ATtiny als Empfänger überhaupt kein Problem ist.
Gruß Chris
Mit "verschiedenste Schaltzustände" meine ich z.B. Folgendes:
00000001 = Funksteckdose 1 aus
10000001 = Funksteckdose 1 an
00000010 = Funksteckdose 2 aus
10000010 = Funksteckdose 2 an
00000011 = Funksteckdose 3 aus
10000011 = Funksteckdose 3 an
00000100 = Funksteckdose 4 aus
10000100 = Funksteckdose 4 an
usw.
Ich würde dem ATtiny dann halt z.B. jeweils ein Byte mit dem entsprechenden Schaltzustand schicken wollen. Die Senderoutine inkl. einem Fifo-Puffer wäre dann auf dem ATtiny.
Chris72622:
Ich würde dem ATtiny dann halt z.B. jeweils ein Byte mit dem entsprechenden Schaltzustand schicken wollen. Die Senderoutine inkl. einem Fifo-Puffer wäre dann auf dem ATtiny.
Das wäre doch die richtige Anwendung für I2C.
Schon mal darüber nachgedacht ?
uxomm:
In den späten Achzigern die Amateurfunkprüfung gemacht - inclusive Morsen - dann ein wenig beim lokalen Club aktiv gewesen (in den frühen Neunzigern), aber nie ein Rufzeichen beantragt (hauptsächlich aus finanziellen Gründen). Später dann mit anderen Dingen beschäftigt.
Aber: das erworbene Grundlagenwissen war mir immer wieder mal sehr nützlich!
Also: nicht sehr aktiv
Prüfung ohne Rufzeichen ?
Musste man das Rufzeichen separat beantragen ?
Das kenn ich so nicht. Aber ich wollte eins haben (ohne CW) und bekam das auch.
Lange Zeit war ich auch recht aktiv, habe aber irgendwann keine Zeit mehr gehabt und alles abgebaut.
Jetzt nur noch mit den Controllern aktiv.
HotSystems:
Prüfung ohne Rufzeichen ?
Musste man das Rufzeichen separat beantragen ?
Das kenn ich so nicht. Aber ich wollte eins haben (ohne CW) und bekam das auch.
mittlerweile hab ich den Ringpuffer auf dem ATtiny85 programmiert und dieser kann auch den 433MHz Sender bedienen.
Ich habe jedoch das Gefühl, dass der Ringpuffer zu schnell geleert wird und die zu sendenden Befehle somit nicht der Reihe nach gesendet werden. Wenn ich dem ATtiny nämlich viele zu sendende Befehle "übergebe", arbeitet er nicht der Reihe nach die "Warteschlange" ab, sobald ich die Verbindung zwischen dem Sender (Arduino Uno) und dem ATtiny trenne, sondern hört einfach auf zu senden.
Hat jmd. von Euch eine Idee, wie ich den Ringbuffer dazu veranlassen kann erst dann den nächsten Befehl zu senden, wenn der letzte zu sendende Befehl gesendet wurde?
Gruß Chris
/*
Funksteckdosen-Sketch für Attiny85, Bootloader 8 MHz intern, arbeitet nur mit 8 MHz intern
Belegung des Attiny85 beim Bootloader brennen und Sketch hochladen:
Arduino Pin 10 1 | \/ | 8 5V
2 | | 7 Arduino Pin 13
3 | | 6 Arduino Pin 12
GND 4 | | 5 Arduino Pin 11
Belegung des Attiny85 nach Upload Sketch:
Arduino Pin 10 1 | \/ | 8 5V
220 Ohm, LED GND 2 | | 7 4,7kOhm, SCL, Arduino A5
433MHz TX-Modul 3 | | 6
GND 4 | | 5 4,7kOhm, SDA, Arduino A4
NOTE! - It's very important to use pullups on the SDA & SCL lines!
Current Rx & Tx buffers set at 32 bytes - see usiTwiSlave.h
*/
#include "TinyWireS.h" // wrapper class for I2C slave routines
#include <RCSwitch.h>
#define I2C_SLAVE_ADDR 0x26 // i2c slave address (38)
#define FIFOSIZE 32 // Einmalig festgelegte Puffergröße
char fifo[FIFOSIZE]; // Der Puffer an sich (in diesem Fall ein char-Array)
byte fifoWriteIndex = 0; // Schreibindex
byte fifoReadIndex = 0; // Leseindex
// 433MHz Modul
RCSwitch myTx = RCSwitch();
const byte txPin = 4; // Ausgang Sender-Daten an ATtiny Pin 3 (kein Tippfehler!)
const byte sendCnt = 3; // max. Anzahl der Aussendungen
// LED
const byte ledPin = 3; // Pin 2 (kein Tippfehler!)
unsigned long lastTime; // Einschaltzeitpunkt festhalten
void setup()
{
TinyWireS.begin(I2C_SLAVE_ADDR); // init I2C Slave mode
pinMode (txPin, OUTPUT); // 433MHz Modul
pinMode (ledPin, OUTPUT); // LED
myTx.enableTransmit(txPin); // Übertragung ermöglichen
myTx.setPulseLength(375); // Pulsweite
myTx.setRepeatTransmit(10); // Anzahl der Sendewiederholungen innerhalb der Library
}
void loop()
{
i2cToFifo(); // I2C nach Fifo, wenn "was" reinkommt
fifoToTx(); // Fifo nach 433MHz Sender
if (millis() - lastTime >= 1000 && digitalRead(ledPin) == HIGH) digitalWrite(ledPin, LOW); // LED ausschalten
}
void i2cToFifo()
{
if (TinyWireS.available()) fifoWrite(TinyWireS.receive()); // Vom Mega angekommenes Zeichen in den Puffer schreiben
}
void fifoWrite(char c) // Schreibfunktion
{
if (c == 'A' || c == 'a' || c == 'B' || c == 'b' || c == 'C' || c == 'c') // Nur bestimmte Zeichen in den Puffer schreiben
{
digitalWrite(ledPin, HIGH); // LED einschalten
lastTime = millis(); // Zeitpunkt festhalten
fifo[fifoWriteIndex] = c; // Schreiben des eingehenden Zeichens an die aktuelle Indexposition
c = fifoWriteIndex; // Aktuelle Indexposition zwischenspeichern (in diesem Fall im c char um Speicherplatz zu sparen)
fifoWriteIndex++; // Indexposition inkrementieren
if (fifoWriteIndex >= FIFOSIZE) fifoWriteIndex = 0; // Wenn das Ende des Puffers erreicht wird, die Schreibposition auf den ersten Index setzen
if (fifoReadIndex == fifoWriteIndex) fifoWriteIndex = c; // Schutzfunktion, wenn mehr Zeichen in den Puffer geschrieben werden sollen, als dieser fassen kann
}
}
void fifoToTx()
{
char c;
if (fifoAvailable()) // Sobald sich mind. ein Zeichen im Puffer befindet, diesen auslesen
{
c = fifoRead(); // Befehl aus Puffer lesen
for (int i = 0; i < sendCnt - 1; i++)
{
switch (c)
{
case 'A':
myTx.send(1381719, 24); // Funksteckdose 1 an (Heizkörper Bad OG)
break;
case 'a':
myTx.send(1381716, 24); // Funksteckdose 1 aus
break;
case 'B':
myTx.send(1394007, 24); // Funksteckdose 2 an (Wlan Bad EG)
break;
case 'b':
myTx.send(1394004, 24); // Funksteckdose 2 aus
break;
case 'C':
myTx.send(1397079, 24); // Funksteckdose 3 an (Leselampe)
break;
case 'c':
myTx.send(1397076, 24); // Funksteckdose 3 aus
break;
}
}
}
}
boolean fifoAvailable() // Diese Funktion prüft, ob sich ein neues Zeichen im Ringbuffer befindet
{
return (fifoReadIndex != fifoWriteIndex); // Ein neues Zeichen befindet sich im Ringbuffer wenn (fifoReadIndex != fifoWriteIndex)
}
char fifoRead() // Lesefunktion
{
char c; // Zeichen initialisieren
c = fifo[fifoReadIndex]; // Zeichen aus Ringbuffer lesen
fifoReadIndex++; // Leseindex um eine Stelle erhöhen
if (fifoReadIndex >= FIFOSIZE) fifoReadIndex = 0; // Beim erreichen des Arrayendes den Leseindex auf null zurücksetzen
return c; // Zeichen zum Abschluss aus der Funktion übergeben
}
-- Bitte auch das letzte Posting von mir (vor diesem hier) lesen. --
Hier noch ein Testsketch für einen Uno um den ATtiny zu beschicken.
Wird hierbei die Geschwindigkeit der zu sendenden Befehle erhöht,
merkt man, dass der Ringpuffer auf dem ATtiny die Befehle nicht lange genug hält.
Sämtliche Tests des Ringpuffers mit einzelnen Zeichen waren erfolgreich.
Es liegt also nicht an der Programmierung des Ringpuffers.
Ich weiss praktisch nicht, wie ich feststellen kann, ob der letzte vom ATtiny zu sendende Befehl vollumfänglich gesendet wurde.
Gruß Chris
Edit: Ich habe eben noch in RCSwitch.cpp delayMicroseconds entdeckt. Gebt Ihr mir Recht, wenn ich behaupte, dass mein Vorhaben mit einem Ringpuffer auf dem ATtiny nicht funktionieren kann, da der Ringpuffer aufgrund dieser Delays auf dem Uno programmiert werden müsste?
Ich befürchte halt, dass mir entweder die RCswitch Library den I2C-Empfang durch delayMicroseconds blockiert, oder der Ringpuffer bereits geleert/abgearbeitet wird, bevor der letzte zu sendende Befehl vollumfänglich versendet wurde.
#include <Wire.h>
const byte ledPin = 13;
unsigned long lastTime;
void setup()
{
Wire.begin();
pinMode(ledPin, OUTPUT);
}
void loop()
{
if (millis() - lastTime >= 5000)
{
sendCmd();
lastTime = millis();
}
if (millis() - lastTime >= 1000 && digitalRead(ledPin == HIGH)) digitalWrite(ledPin, LOW);
}
void sendCmd()
{
static bool haha = 0;
digitalWrite(ledPin, HIGH);
if (haha == 0)
{
atSend('C');
haha = 1;
}
else
{
atSend('c');
haha = 0;
}
}
void atSend(char c)
{
Wire.beginTransmission(0x26); // Startet die I2C-Übertragung an 0x26 (ATtiny85)
Wire.write(c); // Schaltet alle Funksteckdosen aus
Wire.endTransmission(); // Stoppt die I2C-Übertragung
}
Unter Verwendung der TinyWireS Library kann der ATtiny keine Nachrichten empfangen, wenn dieser momentan an einem Delay festhängt. Da die RCSwitch Library Gebrauch von Delays macht (um genauer zu sein von delayMicroseconds), kann aus meiner Sicht somit ein reibungsloser Empfang eingehender I2C-Zeichen nicht gewährleistet werden.
Habt Ihr eine Idee, wie ich mein Vorhaben unter Verwendung eines ATtiny85 doch noch gelöst bekomme? Gibt es evtl. eine Library mit der 433MHz-Module angesprochen werden können, ohne dass libraryintern Gebrauch von Delay gemacht wird, oder besteht für den ATtiny eine Möglichkeit eingehende Zeichen auch dann zu empfangen, wenn dieser grad an einem Delay festhängt?
Was ist nun nochmal das Ziel?
Ein ATtiny85 soll über ein 433MHz-Modul Nachrichten verschicken. Sobald viele Befehle auf einmal zu verschicken sind, soll der ATtiny diese zunächst in einem Ringpuffer zwischenspeichern um sie dann der Reihe nach abarbeiten zu können.
Folgenden, theoretisch denkbaren Weg möchte ich nicht gehen:
Ich könnte den Ringpuffer auf dem Uno erstellen und dann seitens des ATtiny so etwas in der Art von "clearToSend" aufbauen, so dass der Uno nur dann per I2C Zeichen schickt, wenn der ATtiny auch bereit für den Empfang ist. Ich will das Ganze jedoch nicht verkomplizieren.
Chris72622:
Folgenden, theoretisch denkbaren Weg möchte ich nicht gehen:
Ich könnte den Ringpuffer auf dem Uno erstellen und dann seitens des ATtiny so etwas in der Art von "clearToSend" aufbauen, so dass der Uno nur dann per I2C Zeichen schickt, wenn der ATtiny auch bereit für den Empfang ist. Ich will das Ganze jedoch nicht verkomplizieren.
Mit einem Rinpuffer habe ich bisher noch nicht gearbeitet, daher habe ich den 2. Weg für mich als praktikabel angesehen.
In meinem "Rollladen-Controller" habe ich es so gelöst.
Erst wenn der letzte RCSwitch-Befehl abgearbeitet wurde, sendet der Client ein OK und der Controller kann den nächsten Client ansprechen. Der Aufwand ist minimal.