ich bin sowohl hier als auch in der Arduino-Welt neu.
Ich habe folgendes vor:
Über einen Raspberry (I2C-Master) möchte ich eine LED anschalten, welche an einem Arduino Nano hängt.
Später möchte ich allerdings ein Relais statt einer LED über die selbe Art ansteuern.
Folgender Code läuft auf dem Arduino:
#include <Wire.h>
#define SLAVE_ADDRESS 0x07
int number = 0;
int state = 0;
void setup() {
pinMode(13, OUTPUT);
Serial.begin(9600); // start serial for output
// initialize i2c as slave
Wire.begin(SLAVE_ADDRESS);
// define callbacks for i2c communication
Wire.onReceive(receiveData);
Wire.onRequest(sendData);
Serial.println("Ready!");
}
void loop() {
delay(100);
}
// callback for received data
void receiveData(int byteCount){
while(Wire.available()) {
number = Wire.read();
Serial.print("data received: ");
Serial.println(number);
if (number == 13){
digitalWrite(number, HIGH);
delay(5000);
digitalWrite(number, LOW);
}
}
}
// callback for sending data
void sendData(){
Wire.write(number);
}
Die Kommunikation zwischen Raspberry und Arduino funktioniert tadellos.
Das Problem ist, dass die LED nur kurz aufblinkt und sofort wieder erlischt.
Mit dem delay wollte ich die LED allerdings 5 Sekunden angeschalten lassen und danach wieder ausschalten, was aber nicht funktioniert
Vielen Dank für die schnellen Antworten.
Wenn ich delay nicht nutzen kann, wie kann ich dann eine Pause von 5sek generieren?
Ist ein weiteres Steuersignal vom Raspberry die einzige Möglichkeit?
tomml:
Vielen Dank für die schnellen Antworten.
Wenn ich delay nicht nutzen kann, wie kann ich dann eine Pause von 5sek generieren?
Ist ein weiteres Steuersignal vom Raspberry die einzige Möglichkeit?
Du kannst einen Timer verwenden, da gibt es z.B. von combie den "wahren simple Timer".
Suche mal hier im Forum.
Du kann dir einen Timer machen, dann siehst du wie simpel das ist.
In der callback merkst du dir nur, dass eine 13 gekommen ist. (Wofür ist z.B. state?)
In loop prüfst du dies, merkst dir die Zeit, machst die LED an, und stellst deinen state-Merker auf einen anderen Zustand.
Ausserdem prüfst du in loop, ob die 5 Sekunden seitdem um sind und machst dann die Led wieder aus.
tomml:
Versteh' leider nicht, was das Problem ist?
Für eine monostabile Kippstufe von fünf Sekunden benötigst Du keinen Interrupt, daher kannst Du die ISR auf ein Minimum reduzieren und das Kippen dem Hauptprogramm überlassen. Wenn Du nur ein Byte schickst, ist das schon atomar, so daß m. E. keine weiteren Maßnahmen notwendig sind.
Über Details, beispielsweise ob die monostabile Kippstufe retriggerbar sein soll, muß man sicher noch nachdenken.
Ich habe mit einem UNO als Master und einem Mega2560 als Slave getestet:
// I2C-Slave
#include <Wire.h>
volatile byte wert;
const uint32_t flopIntervall = 5000;
uint32_t aktMillis, flopMillis;
void setup() {
Serial.begin(9600);
Serial.println("Slave Start");
Wire.begin(21);
Wire.onReceive(receiveEvent);
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
aktMillis = millis();
if (wert == 1) {
wert = 0;
flopMillis = aktMillis;
digitalWrite(LED_BUILTIN, HIGH);
Serial.println("Ein");
}
if ((aktMillis - flopMillis >= flopIntervall) && digitalRead(LED_BUILTIN))
{
digitalWrite(LED_BUILTIN, LOW);
Serial.println("Aus");
}
}
// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany) {
for (byte j = 0; j < howMany; j++) {
wert = Wire.read(); // receive byte
}
}