Frage zu "Kommunikation ATtiny84 zu Arduino MEGA"

Hallo,
da ich mit der Einbindung des RFM12B in meinen Sketch auf dem MEGA nicht weiter komme (und es auch keine Lösung (RFM12B beim DUE) gibt, habe ich folgende Idee:

Ich nutze zum Empfang eines RFM12B-Senders ein eigenes Empfangsmodul (ATtiny84), welches dann die empfangenen Daten an einen Arduino MEGA sendet.

#include <SoftwareSerial.h>
#include <JeeLib.h>


SoftwareSerial mySerial(10, 11); // RX, TX am ATtiny84 --> Pin 18, 19 am MEGA

#define MYNODE 30            //node ID Empfänger
#define freq RF12_868MHZ     //Frequenz
#define group 99             //Gruppe

int Sender;

typedef struct {
  int Temperatur;
  int Batterie;
  int Versuch;
} PayloadSender;
PayloadSender rx;


void setup () {
  mySerial.begin(9600);
  rf12_initialize(MYNODE, freq, group); // Initialise the RFM12B
}


void loop() {
  if (rf12_recvDone() && rf12_crc == 0 && (rf12_hdr & RF12_HDR_CTL) == 0) {
    Sender = rf12_hdr & 0x1F;
    rx = *(PayloadSender*) rf12_data;
    int Temperatur = rx.Temperatur;
    int Batterie = rx.Batterie;
    int Versuch = rx.Versuch;
    if (RF12_WANTS_ACK) {                  // Send ACK if requested
      rf12_sendStart(RF12_ACK_REPLY, 0, 0);
    }
    mySerial.println(Sender);
    mySerial.println(Temperatur);
    mySerial.println(Batterie);
    mySerial.println(Versuch);  
  }
}
///////////////////////////////////////////////
//passender Sketch im MEGA
///////////////////////////////////////////////
typedef struct {
  int Sender;
  int Temperatur;
  int Batterie;
  int Versuch;
} PayloadEmpfang;
PayloadEmpfang Empfaenger;


void setup1 () {
  Serial.begin(9600);
  Serial.begin(9600);
}

void loop() {
  int i = 0;
  if Serial1.available() {
    while Serial1.available() {
      Empfaenger[i++] = Serial1.read();
      delay(2);
    }
    //Werte anzeigen...
    Serial.println(Empfaenger.Sender);
    Serial.println(Empfaenger.Temperatur);
    Serial.println(Empfaenger.Batterie);
    Serial.println(Empfaenger.Versuch);
    //Empfangsarray wieder löschen...
    for (int x = 0; x < Empfaenger.length(); x++) {
      Empfaenger[x] = NULL;
    }    
  }
}

Könnte das so funktionieren, oder habt Ihr andere Ideen oder Meinungen?

MfG paulinchen (Entschuldigung, aber die neue Forum-Software schon ist sehr “seltsam”…

Als aller erstes: Läuft der Code? Wahrscheinlich nicht.

ich kenn mich mit dem RFM12B nicht aus, aber solange das funktioniert sollte die Kommunikation der beiden AVR nicht mehr so schwer sein. Ein paar Sachen sind mir aufgefallen:

Allgemein: Der ATtiny ist ein 8 bit Controller, daher kann er mit 8 bit Werten am schnellsten umgehen. Das gleiche gilt für Serial. Benutz “int” nur da, wo du tatsächlich eine ±16 bit Zahl brauchst, sonst “byte” (Werte 0-255). Das macht die ganze sache schon ein wenig flotter.

Zu Serial: “print()” und “println()” senden eine formatierte Zeichenkette, die vom Mensch gelesen werden kann. D. h., wenn du nur Werte zw. zwei µCs übertragen willst, nimm lieber “write(byte)”. Sonst musst du am anderen Ende wieder zurückformatieren mit “parseInt()” was extrem langsam ist.

#include <SoftwareSerial.h>
#include <JeeLib.h>

SoftwareSerial mySerial(10, 11); // RX, TX am ATtiny84 --> Pin 18, 19 am MEGA

#define MYNODE 30            //node ID Empfänger
#define freq RF12_868MHZ     //Frequenz
#define group 99             //Gruppe

byte Sender;  //hier in "byte" geändert

typedef struct {
  byte Temperatur;
  byte Batterie;
  byte Versuch;
} PayloadSender;
PayloadSender rx;


void setup () {
  mySerial.begin(9600);
  rf12_initialize(MYNODE, freq, group); // Initialise the RFM12B
}


void loop() {
  if (rf12_recvDone() && rf12_crc == 0 && (rf12_hdr & RF12_HDR_CTL) == 0) {
    Sender = rf12_hdr & 0x1F;
    rx = *(PayloadSender*) rf12_data;
    byte Temperatur = rx.Temperatur; //hier in "byte" geändert
    byte Batterie = rx.Batterie;
    byte Versuch = rx.Versuch;
    if (RF12_WANTS_ACK) {                  // Send ACK if requested
      rf12_sendStart(RF12_ACK_REPLY, 0, 0);
    }
    mySerial.write(Sender);  //hier in "write" geändert
    mySerial.write(Temperatur);
    mySerial.write(Batterie);
    mySerial.write(Versuch);  
  }
}
typedef struct { //hier in "byte" geändert
  byte Sender;
  byte Temperatur;
  byte Batterie;
  byte Versuch;
} PayloadEmpfang;
PayloadEmpfang Empfaenger;


void setup() {  //sollte bsetimmt nicht "setup1()" heißen
  Serial.begin(9600);
  Serial1.begin(9600); //sollte bestimmt nicht auch "Serial" heißen
}

void loop() {
  byte i = 0;
  if Serial1.available() {
    while Serial1.available() {
      Empfaenger[i++] = Serial1.read();
      delay(2);  //naja
    }
    //Werte anzeigen...
    Serial.println(Empfaenger.Sender);
    Serial.println(Empfaenger.Temperatur);
    Serial.println(Empfaenger.Batterie);
    Serial.println(Empfaenger.Versuch);
  }
}

Löschen des Empfangsarrays? Das lass mal lieber. :wink:

Ich persönlich hab schon schlechte Erfahrung mit der Zuverlässigkeit von Software Serial auf den Tinys gemacht. (Läuft da überhaupt Software Serial?) Wenn die Übertragungsstrecke nicht zu groß ist, empehle ich dir I²C zu verwenden, das sind auch nur zwei Drähte und in der Regel sehr zuverlässig.

Mal ne ganz andere Sache: Warum sparst du nicht den Tiny ein und hängst den RFM12B direkt an den SPI vom Mega?

Marv

Danke für die Antwort.

Der Code war nur ein Gedankenmodell zur prinzipiellen Vorgehensweise. Ich habe ihn noch nicht getestet, da ich erst die Hardware aufbauen muß.

Nach vielen Stunden läuft jetzt der RFM12B direkt an meinem MEGA. Die jelib-Bibliothek ist leider sehr fehlerhaft.

Da es auch keine Bibliothek für den Arduino DUE gibt (für welchen ich meinen Sketch parallel entwickle), werde ich wohl doch lieber einen ATtiny als Empfänger verwenden.

Welche Bibliothek müßte ich denn verwenden, um auf dem ATtiny84 einen I2C-Bus zu simulieren?

MfG paulinchen

hi,

tinywire, gibt's für master und slave (zb im playground).
ich hab' sie nur kurz mal ausprobiert und hatte keine probleme. dann hab' ich es aber nicht geschafft, einen ir-empfänger für meine fernbedienung am tiny zum laufen zu bringen, deswegen nehm ich jetzt einen atmega8 und einen 328er. zwei deshalb, weil neben der fastSPI wiederum kein ir-empfang möglich ist.

gruß stefan

paulinchen:
Da es auch keine Bibliothek für den Arduino DUE gibt (für welchen ich meinen Sketch parallel entwickle), werde ich wohl doch lieber einen ATtiny als Empfänger verwenden.

Es gibt bereits SPI bibliotheken für den Due. Den Rest für den RFM12B zu portieren halte ich für weniger aufwendig als einen weiteren Controller einzusetzen, der wiederum beschalten werden will.

paulinchen:
Welche Bibliothek müßte ich denn verwenden, um auf dem ATtiny84 einen I2C-Bus zu simulieren?

Ich seh grade: I²C und SPI sind beim ATtiny wegen USI implementierung an den gleichen Pins - was die gleichzeitige Benutzung erschwert bzw. wahrscheinlich sogar unmöglich macht.

Ich würde dir empfehlen, auf den ATtiny zu verzichten und lieber eine Softwarelösung findest. Sobald SPI mal auf dem Due läuft, sollte es keine Probelme geben. Weitere Controller und serielle Schnittstellen erhöhen nur die Fehleranfälligkeit und den Debugaufwand des Systems. Wenn du schon ein Due hast, kannst du auch die Leistung ausnutzen und musst nicht über hundert (ich weiß, ich übertreibe :wink: ) Umwege probieren, an dein Ziel zu kommen.

Falls du doch mt dem Tiny fahren willst: Teste das ganze mal mit Serial zw. Tiny und Mega, wenn das läuft sollte es beim Due umso einfacher werden.

Also ich verwende als Empfänger einen Atmega328 und sende dann die Daten über I2C an den Mega. Das klappt problemlos. Muss es denn unbedingt ein ATtiny sein?

hi,

naja, am preis kanns nicht liegen, bei 1,40€ versandkostenfrei für einen atmega8, aber ich versteh' schon, daß sie es versuchen will...

würde ich etwas finden, mit dem ich den ir-empfänger meiner fernbedienung auslesen kann, würd' ich auch einen tiny nehmen.

gruß stefan

Einen ATtiny84 wollte ich verwenden, da ich diesen auch als Sender + RFM12B verwende. Und nun schon mal weis, wie ich den programmieren kann usw. Ein 328 ist ja schon wieder anders, größer...

Mein Sketch auf dem MEGA funktioniert nun, aber die Einbindung des RFM12B -Moduls war schon schwierig, da die Jeelib-Bibliothek sehr fehlerhaft ist (für den MEGA). Aber jetzt läuft es ja...

Ich werde aber wohl erst mal probieren, das RFM12B auch direkt am DUE zum laufen zu bringen. Gibt es hier bereits SPI-Bibliotheken für den Due an welchen ich mich orientieren kann?

MfG paulinchen