RCSwitch - Arduino Freeze

Hallo an alle,

ich bin dabei mir für meine Wohnzimmerlampe eine Lampensteuerung zu bauen welche über 433 MHz angesteuert wird.
Leider hänge ich gerade beim hoch und runter Dimmen fest, weil mein arduino jedes mal einfriert :frowning: könnt ihr mir da helfen, habe schon den ganzen Tag nach einer Lösung gegooglet.

Problembeschreibung Freeze:
Wenn ich auf der Fernbedienung den Knopf zum dimmen Drücke wird der Befehl erkannt und der Arduino springt zum Abschnitt --> brightness:
In diesem Programmabschnitt soll bei gehaltener Dimmtaste schnell gedimmt werden, bei mehrfachem Drücken wird der Wert nur um jeweils 1 subtrahiert. Sobald der Wert auf 200 Abgesunken ist wird der arduino immer langsamer und friert ein.
Wenn ich den Code in diesem Abschnitt auskommentiere ---> kein freeze
Nach einem Reset geht alles wieder. Wenn ich den Aufbau mit Tastern realisiere funktioniert alles.

Hat irgendjemand eine Idee?

Hier der Code:

#include <RCSwitch.h>

RCSwitch mySwitch = RCSwitch();

// Variables:
// IO Pins
int SpotPin = 9;
int AmbiPin = 10;

// 433 Variables
int SpotTgl = LOW;
int AmbiTgl = LOW;
int SpotSet = LOW;
int AmbiSet = LOW;
int NumBttn;
int OkBttn = LOW;
int SpotInc = LOW;
int SpotDec = LOW;
int AmbiInc = LOW;
int AmbiDec = LOW;

// Others
int SpotState = HIGH;
int SpotBrghtns = 255;
int AmbiState = HIGH;
int AmbiBrghtns = 255;
int BttnRlsd = HIGH;
long LastBttnPrss = 0;
long LastInc = 0;

// Changable Values
long BttnTmt = 300;
long IncSpd = 10;
long FadeAmnt = 5;

void setup() {
  pinMode(SpotPin, OUTPUT);
  pinMode(AmbiPin, OUTPUT);
  Serial.begin(9600);
  mySwitch.enableReceive(0);  // Receiver on inerrupt 0 => that is pin #2

}

void loop() {
  // 433 MHz Empfang
  if (mySwitch.available()) {

    long value = mySwitch.getReceivedValue();

    // Positive Flanke: Knopf gerade gedrückt
    if (millis() - LastBttnPrss > BttnTmt) {
      BttnRlsd = HIGH;
    }
    else {
      BttnRlsd = LOW;
    }
    LastBttnPrss = millis();

    mySwitch.resetAvailable(); 

    Serial.print("Received ");
    Serial.print( mySwitch.getReceivedValue() );
    Serial.print(" / ");
    Serial.print( mySwitch.getReceivedBitlength() );
    Serial.print("bit ");
    Serial.print("Protocol: ");
    Serial.println( mySwitch.getReceivedProtocol() );

    // Auswertung Funksignale
    if (value == 1064981) {
      SpotInc = HIGH;
      goto brightness;
    }
    if (value == 1064980) {
      SpotDec = HIGH;
      goto brightness;
    }
    if (value == 1048596) {
      AmbiInc = HIGH;
      goto brightness;
    }
    if (value == 1048597) {
      AmbiDec = HIGH;
      goto brightness;
    }
    if (value == 1052693) {
      SpotTgl = HIGH; 
      goto toggles;
    }
    if (value == 1052692) {
      AmbiTgl = HIGH;
      goto toggles;
    }
    if (value == 4373) {
      SpotSet = HIGH;
    }
    if (value == 4372) {
      AmbiSet = HIGH;
    }
    if (value == 16661) {
      OkBttn = HIGH;
    }
    if (value == 1045) {
      NumBttn = 1;
    }
    if (value == 1044) {
      NumBttn = 2;
    }
    if (value == 17429) {
      NumBttn = 3;
    }
    if (value == 17428) {
      NumBttn = 4;
    }
    if (value == 5141) {
      NumBttn = 5;
    }
    if (value == 5140) {
      NumBttn = 6;
    }
    if (value == 21525) {
      NumBttn = 7;
    }
    if (value == 21524) {
      NumBttn = 8;
    }
    if (value == 277) {
      NumBttn = 9;
    }
    if (value == 276)  {
      NumBttn = 0;
    }

  }

  else {
    goto output;
  }

toggles:
  // Toggle Switches
  if (BttnRlsd == HIGH) {  // Nur abarbeiten wenn ein Knopf gerade gedrückt wurde

    // Spot Toggle   
    if (SpotTgl == HIGH) {
      if (SpotState == HIGH) {
        SpotState = LOW;
      }
      else {
        SpotState = HIGH;
      }
    }

    //  Ambi Toggle  
    if (AmbiTgl == HIGH) {
      if (AmbiState == HIGH) {
        AmbiState = LOW;
      }
      else {
        AmbiState = HIGH;
      }      
    }
  }
  // Reset Variable
  SpotTgl = LOW;
  AmbiTgl = LOW;
  goto output;

brightness:
  // Spot Helligkeit hoch und runter dimmen

  // Spot
  if (SpotInc == HIGH && SpotBrghtns < 255) {
    if (BttnRlsd == HIGH) {
      SpotBrghtns = SpotBrghtns + 1;
    }
    else {
      SpotBrghtns = SpotBrghtns + 5;
    }
  }

  if (SpotDec == HIGH && SpotBrghtns > 0) {
    if (BttnRlsd == HIGH) {
      SpotBrghtns = SpotBrghtns - 1;
    }
    else {
      SpotBrghtns = SpotBrghtns - 5;
    }
  }
  Serial.println(SpotBrghtns);
  SpotInc = LOW;
  SpotDec = LOW;

output:
  // Schreibe Ausgangshelligkeit an Pin
  // Spot
  if (SpotState == HIGH)  {
    analogWrite(SpotPin, SpotBrghtns);
  }
  else {
    analogWrite(SpotPin, 0);
  }
  // Ambi
  if (AmbiState == HIGH)  {
    analogWrite(AmbiPin, AmbiBrghtns);
  }
  else {
    analogWrite(AmbiPin, 0);
  }
}

Ist doch kein Freeze :sweat_smile:. Wenn ich eine LED als Heartbeat verwende blinkt diese durchgehend.
Habe daraufhin mal die Kabel zur LED abgezogen und siehe da, es geht wieder. Muss wohl ein geschirmtes Kabel zum Receiver legen oder so.

EDIT:
http://forum.arduino.cc/index.php?topic=146679.0
Werde wohl nicht um einen neuen Receiver kommen.

In der Zwischenzeit habe ich eine neue Frage: Wie bekomme ich die Tastenanschläge der Fernbedienung aneinandergereiht?
z.B. 1+2+5 = 125
Meine Idee wäre ja (1*10+2)*10+5=125 oder gibts da nen Trick?

Du hast vorher wohl Basic programmiert.

Für C vergiß goto.
Du kannst alles ohne goto machen einfach die Programmteile in Funktionen schreiben und aufrufen.

z.B. 1+2+5 = 125
Wenn Du die Zahlen als Ashii in einem array hast, mit null terminieren und dann zahl = atoi(array).

Grüße Uwe

oder gibts da nen Trick?

Ja, das ist der Trick, wenn man atoi für overkill hält:

// Variablendeklarationen sind genauso wichtig wie ausführbare Anweisungen
static unsigned long Wert; // sammelt mehrere Ziffern zu einer Dezimalzahl 
byte neueZiffer;   // entspricht einer gedrückten Taste der FB ( 0 ... 9 oder ENTER )

if  (neueZiffer >=0 && neueZiffer <=9 ) Wert = Wert*10+neueZiffer;  
else { Verarbeite(Wert) ; Wert=0; }

Edit: Variablendeklarationen sind genauso wichtig wie ausführbare Anweisungen

Hi
Kannst du mal schreiben welche Fernbedienung du hast? Ich suche nämlich auch noch eine Funk-Fernbedienung für meine Lichtsteuerung. Habe zwei unterschiedliche von diesen X10 Fernbedienungen (siehe mein Thread dort: X10 Funkfernbedienungen (zB von Medion Digitainer) empfangen - Deutsch - Arduino Forum), eine sogar mit einem kleinen Scrollrad was ideal zum dimmen wäre. Aber leider kann man die Codes von den Fernbedienungen nicht mit der RCSwitch-Lib oder einer anderen mir bekannten Lib auslesen. Die Fernbedienungen gibts zB bei Pollin für kleines Geld (unter 8 Euro).

Gruß
Jarny

Du hast vorher wohl Basic programmiert.

Für C vergiß goto.
Du kannst alles ohne goto machen einfach die Programmteile in Funktionen schreiben und aufrufen.

z.B. 1+2+5 = 125
Wenn Du die Zahlen als Ashii in einem array hast, mit null terminieren und dann zahl = atoi(array).

Damit hast du Recht. In der schule vor 8 Jahren mal :slight_smile: Im Beruf dann an der S7. Dies Hier ist mein erstes Programm und Projekt. :roll_eyes: Werde deine Kritik mal Umsetzen. Dann mal die Zahlen in ein Array bekommen. :cold_sweat:

Hi
Kannst du mal schreiben welche Fernbedienung du hast?

Hey Jarny,

Benutze ne Harmony 555 in kombination mit einem One For All HC8100 IR/RF Wandler. Gibt es für ein paar Euro in der Bucht
In der Harmony habe ich das ganze als HC8300 Gerät eingebunden. Damit schalte ich dann auch meine Intertechno Dosen.
Es gibt in der Harmony Bibliothek auch ein Intertechnogerät, interessanterweise funktioniert es dann nicht obwohl es die gleichen Hauscodes als auswahl gibt.
http://imagizer.imageshack.us/v2/100x75q90/812/q1j8.jpg

Für alle interessierten, hier ein paar Bilder vom elektrischen Aufbau und ein Video im Betrieb mit dem Fade Demo Programm. Sorry für die Qualität, meine Kamera ist gerade leer :frowning:

Die Lampen schalten übrigens invertiert obwohl beide Ausgänge am Arduino Parralel schalten.
Die Stripes haben eine Stromregelung on board und werden extern über einen MOSFET gedimmt welcher die Lampe bei Ansteuerung Einschaltet.
Die Spots werden über keine Konstantstromquelle von Anvilex betrieben. Die KSQ hat einen PWM Eingang, welcher intern über einen Pull-Up Widerstand auf 2,5V=100% gelegt wird. Um ihn zu Dimmen lege ich ihn mit einem N2222 auf Ground 0V=0% welcher bei Ansteuerung die Lampe abschaltet.

Funkenschuhster:
Hey Jarny,

Benutze ne Harmony 555 in kombination mit einem One For All HC8100 IR/RF Wandler. Gibt es für ein paar Euro in der Bucht
In der Harmony habe ich das ganze als HC8300 Gerät eingebunden. Damit schalte ich dann auch meine Intertechno Dosen.
Es gibt in der Harmony Bibliothek auch ein Intertechnogerät, interessanterweise funktioniert es dann nicht obwohl es die gleichen Hauscodes als auswahl gibt.

Ah ok, eine Harmony und ein IR/RF Umsetzer. Schade, ich dachte du hättest so eine günstige X10 Fernbedienung von Pollin. Wenn man mal googelt nach '433mhz Remotes' dann bekommt man im Prinzip zu 99% die Fernbedienungen mit max. 8 Tasten für Funksteckdosen. Die restlichen 1% sind dann die X10-Funkfernbedienungen, die, wie eine normale Fernbedienung, sämtliche Tasten bietet um Multimediageräte zu steuern.
Mein Problem ist halt, dass es dafür keine Library gibt um die Tasten auszulesen :frowning:

Gruß
Jarny