Arduino und Attiny45 - Kommunikation möglich?

Hallo zusammen,

bei der Programmierung einer Fahrradcomputer-Software kommt bei mir das Problem auf, dass zu viele Abfragen die Auslesung des Hallsensors (für die Geschwindigkeitsermittlung) einschränken.. Nun bin ich auf den Gedanken gekommen, mit einem Attiny45 den Sensor separat auszulesen und die errechnete Geschwindigkeit zum Atmega328 zu schicken.. Im Netz bin ich bisher nur auf Berichte gestoßen, die von der Debughilfe (per serielle Kommunikation) eines Attinys handelten. Hierbei ist allerdings das Problem, dass der Arduino dann keine anderen Aktivitäten ausführen kann. Nun ist meine Frage, ob eine Serielle Kommunikation bzw. überhaupt eine Kommunikation jeglicher Art zwischen den beiden ICs umsetzbar ist..

Oder hat sonst noch Jemand eine Idee, wie man das Problem auf eine andere Art und Weise lösen könnte ?

Gruß und Dank reuter328

Bei meinem MP3-Player habe ich einen ATtiny85 mittels I2C und einer Meldeleitung mit dem UNO verbunden. Der ATtiny85 hat die IR-Fernbedienung ausgelesen und den Befehl an den UNO weitergeleitet. Könntest Du auch so machen.

Klar ... kann man über SPI oder I2C machen. Allerdings ist der Grund für schlechte Performance meiste schlechte Programmierung :-) Bevor Du also darüber nachdenkst, einen zweiten Prozessor einzusetzen, solltest Du Deinen Code vielleicht nach Optimierungs-Potenzial durchforsten.

Wenn Du einen Tiny einsetzen möchtest, solltest Du Dir aber auch Gedanken über die Entwicklungsumgebung machen. Ich nutze dafür in aller Regel ATMEL Studio, da man damit auch vernünftig in der Hardware debuggen kann.

…mittlerweile habe ich eine Master-Slave-SPI Kommunikation zwischen zwei Arduinos am laufen. Das klappt soweit auch ganz gut. Nun bin ich dabei den einen Arduino durch einen Attiny45 zu ersetzen. Hierbei ist das Problem, dass der Attiny nichts mit der Bibliothek <SPI.h> anfangen kann. Im Netz habe ich nun diese Ersatz-library gefunden: <tinySPI.h>…diese wiederum unterstützt nicht alle gängigen Methoden (z.B. SPI.setClockDivider) der normalen SPI-library…

…da am Attiny45 kein Pin als SlaveSelect vorgesehen ist, bin ich davon ausgegangen, dass man einfach einen als diesen deklarieren kann…richtig?

Gruß und Dank
reuter328

@jurs: Neben dem Hallsensor, habe ich eine Stoppuhr (mit millis(), dementsprechend einige if-abfragen) und drei Helligkeitssensoren am laufen.. Mir ist bewusst, dass höchst wahrscheinlich noch ein paar Stellen des Codes optimiert werden könnten;)

..nun reizt es mich aber auch irgendwie, die oben genannte master-Slave Beziehung bei einem attiny zu realisieren:)

Dank und Gruß reuter328

wie ich schon geschrieben habe: wenn Du einen Tiny einsetzt, solltest Du Dich vom Gedanken verabscheiden, den über die Arduino-IDE zu programmieren. Die Bibliotheken schleppen einfach viel zu viel Overhead mit. Das ist übrigens auch der Grund für Deine schlechte Performance.

Mach es richtig und programmier zumindest den Tiny per ATMEL Studio oder was ähnlichem ... oder verzichte KOMPLETT auf Arduino-Bibliotheken und mach es mit nativem C. Da rächen sich dann aber die Unzulänglichkeiten der Arduino IDE. Sie wurde halt für einen schnellen, unkomplizerten Einstieg konzipiert ... für wirklich professionell umgesetzte Projekte ist sie aber sub-obptimal. Das beginnt schon bei den fehlenden Debug-Möglichkeiten außerhalb von Serial.Print() Sinnvoll geht sowas nur mit Inline-Debugging in der Hardware ... womit wir wieder bei ATMEL Studio sind.

Es sollte Dich also eher reizen performanten, professionellen Code zu schreiben ... anstatt wild irgendwelche zusätzliche Hardware zusammen zu stöpseln ;) Versteh mich nicht falsch: Arduino mit seinen Bibliotheken ist super, um einen einfachen Einstieg in ein Thema zu finden. Wenn Du aber wirklich ernsthaft entwickeln willst, wirst Du Dich früher oder später in die Grundlagen einarbeiten müssen, die Dir die Bibliotheken momentan abnehmen / vor Dir verbergen.

@mgcss: Vielen Dank für die Anregungen. Ich werde mich mal in den nächsten Tagen/Wochen mit Atmel Studo befassen und mal ein wenig experimentieren.

…mittlerweile bin ich im Netz auf eine recht “einfache” Variante gestoßen, die mein Problem gelöst hat. :slight_smile:
Über I2c habe ich nun sowohl ein OLED, als auch ein Attiny45 am laufen…Das klappt soweit auch ganz gut.
Nun möchte ich allerdings nicht nur eine Variable vom Slave zum Master schicken, sondern gleich zwei…Hat da jemand eine Idee, wie man diese differenzieren bzw. irgendwie codieren kann, um sie beim Empfang auseinanderhalten zu können?

Hier noch die beiden funktionierenden Codes (Master/Slave) für die I2c-Kommunikation:

//ARDUINO-UNO-MASTER
/*
Attiny45:SDA = pin 5
         SCL = pin 7
Arduino:SDA = A4
        SCL = A5
SDA zu SDA // SCL zu SCL
https://thewanderingengineer.com/2014/02/17/attiny-i2c-slave/
*/
#include <Wire.h>
 
void setup()
{
 Wire.begin(); // join i2c bus (address optional for master)
 Serial.begin(9600); // start serial for output
}
 
void loop()
{
 Wire.requestFrom(4,1); // request 1 byte from slave device address 4
 
while(Wire.available()) // slave may send less than requested
 {
 int i = Wire.read(); // receive a byte as character
 Serial.println(i); // print the character
 }
 
delay(500);
}
//ATTINY-SLAVE
/*
Attiny45:SDA = pin 5
         SCL = pin 7
Arduino:SDA = A4
        SCL = A5
SDA zu SDA // SCL zu SCL
https://thewanderingengineer.com/2014/02/17/attiny-i2c-slave/
*/
#define I2C_SLAVE_ADDRESS 0x4 // Address of the slave
 
#include <TinyWireS.h>
 
int i=0;

void setup()
{
    TinyWireS.begin(I2C_SLAVE_ADDRESS); // join i2c network
    //TinyWireS.onReceive(receiveEvent); // not using this
    TinyWireS.onRequest(requestEvent);
 
    // Turn on LED when program starts
    pinMode(3, OUTPUT);
    digitalWrite(3, HIGH);
}
 
void loop()
{
    // This needs to be here
    TinyWireS_stop_check();
}
 
// Gets called when the ATtiny receives an i2c request
void requestEvent()
{
    TinyWireS.send(i);
    i++;
}

Für Ideen und Anregungen wäre ich sehr dankbar;)

Dank und Gruß
reuter328

reuter328: Nun möchte ich allerdings nicht nur eine Variable vom Slave zum Master schicken, sondern gleich zwei..Hat da jemand eine Idee, wie man diese differenzieren bzw. irgendwie codieren kann, um sie beim Empfang auseinanderhalten zu können?

Zwei Bytes anfordern, zwei lesen (ungetestet):

Wire.requestFrom(4,2); // request 2 bytes from slave device address 4

while(Wire.available()) // slave may send less than requested
 {
 byte eins = Wire.read(); // receive a byte as character
 byte zwei = Wire.read(); // receive a byte as character
 Serial.print(eins); // print the character
 Serial.print("  ");
 Serial.println(zwei); // print the character
 }