try to fix irsend blueled timer/pwm mess
[svn42.git] / rf433ctl / rf433ctl.pde
index b442b96..68d9f08 100644 (file)
@@ -11,8 +11,8 @@
 #define IR_MOVEMENT_PIN 9
 #define ONE_WIRE_PIN 8
 #define PANIC_BUTTON_PIN 7
-#define BLUELED_PWM_PIN 6
-#define BLUELED2_PWM_PIN 11
+#define PANICLED_PWM_PIN 6
+#define BLUELED_PWM_PIN 11
 #define PHOTO_ANALOGPIN 0
 //movement is reported if during IR_SAMPLE_DURATION at least IR_TRESHOLD ir signals are detectd
 #define IR_SAMPLE_DURATION 12000
@@ -48,6 +48,7 @@ const char YAMAHA_VCR =0xF0; //Input VCR
 const char YAMAHA_EXT51DEC =0xE1; //Input Ext. Decoder On/Off
 
 const char YAMAHA_TUNER_PLUS =0x08; //Tuner Next Station 1-7  (of A1 - E7)
+const char YAMAHA_TUNER_MINUS =0x88; //Tuner Prev Station 1-7  (of A1 - E7)
 const char YAMAHA_TUNER_ABCDE =0x48; //Tuner Next Station Row A-E (of A1 - E7)
 
 const char YAMAHA_MUTE =0x38;
@@ -79,17 +80,6 @@ const char YAMAHA_EFFECT5 =0x91; //Effect Toggle 70mm Sci-Fi / 70mm Spectacle
 const char YAMAHA_EFFECT6 =0x51; //Effect Toggle 70mm General / 70mm Adventure
 const char YAMAHA_P5 =0xFB; //P5 PRT (1 Main Bypass)? (1587674115)
 
-
-void send_yamaha_ir_signal(char codebyte)
-{
-  unsigned long int code = codebyte & 0xFF;
-  code <<= 8;
-  code |= (0xff ^ codebyte) & 0xFF;
-  code |= YAMAHA_CODE_BASE;
-  irsend.sendNEC(code,YAMAHA_CODE_BITS);
-  Serial.println("Ok");  
-}
-
 //********************************************************************//
 
 typedef struct {
@@ -255,8 +245,8 @@ ISR(TIMER1_COMPA_vect)
 
 void send_frame(const word_t w)
 {
-  if (frame_finished == 0)
-    for(;;)
+  if (frame_finished != 1)
+    for(;;) //wait until sending of previous frame finishes
       if (frame_finished)
       {
         delay(150);
@@ -264,7 +254,7 @@ void send_frame(const word_t w)
       }
   word_cnt = 0;
   frame_finished = 0;
-  init_word(w);      
+  init_word(w);
 }
 
 void check_frame_done()
@@ -273,6 +263,7 @@ void check_frame_done()
   {
     Serial.println("Ok");
     frame_finished=1;
+    delay(120);
   }
 }
 
@@ -342,29 +333,46 @@ bool wait_millis(unsigned long ms)
 unsigned int flash_led_time_=0;
 unsigned int flash_led_brightness_=255;
 unsigned int flash_led_delay_=8;
-void calculate_led_level(unsigned int pwm_pin)
+unsigned int flash_led_selected_=0;
+void calculate_led_level()
 {
-  if (flash_led_time_ == 0)
+  if (flash_led_time_ == 0 || flash_led_selected_ == 0)
     return;
   if (wait_millis(flash_led_delay_))
     return;
   flash_led_time_--;
   int c = abs(sin(float(flash_led_time_) / 100.0)) * flash_led_brightness_;
   //int d = abs(sin(float(flash_led_time_) / 100.0)) * flash_led_brightness_;
-  analogWrite(BLUELED2_PWM_PIN, 255-c);
-  if (flash_led_brightness_ == 255)
+  if (flash_led_selected_ && (1 << BLUELED_PWM_PIN))
+    analogWrite(BLUELED_PWM_PIN, 255-c);
+  else
+    analogWrite(BLUELED_PWM_PIN,255); //off
+  if (flash_led_selected_ && (1 << PANICLED_PWM_PIN))
   {
     if (flash_led_time_)
-      analogWrite(BLUELED_PWM_PIN, 255-c);
+      analogWrite(PANICLED_PWM_PIN, c);
     else
-      analogWrite(BLUELED_PWM_PIN, c);
+      analogWrite(PANICLED_PWM_PIN, 255-c);
   }
+  else
+    analogWrite(PANICLED_PWM_PIN,255); //off
 }
 
-void flash_led(unsigned int times, unsigned int brightness_divisor, unsigned int delay_divisor)
+void flash_led(unsigned int times, unsigned int brightness_divisor, unsigned int delay_divisor, unsigned int led_selector)
 {
-  unsigned int new_flash_led_brightness = 255 / brightness_divisor;
-  unsigned int new_flash_led_delay = 8 / delay_divisor;
+  unsigned int new_flash_led_brightness = 255;
+  unsigned int new_flash_led_delay = 8;
+  flash_led_selected_=led_selector;
+  if (times == 0 || led_selector == 0)
+  {
+    analogWrite(PANICLED_PWM_PIN,255); //off
+    analogWrite(BLUELED_PWM_PIN,255); //off
+    return;
+  }
+  if (brightness_divisor > 1) //guard against div by zero
+    new_flash_led_brightness /= brightness_divisor;
+  if (delay_divisor > 1)  //guard against div by zero
+    new_flash_led_delay /= delay_divisor;
   if (flash_led_time_ == 0 || new_flash_led_brightness > flash_led_brightness_)
     flash_led_brightness_=new_flash_led_brightness;
   if (flash_led_time_ == 0 || new_flash_led_delay < flash_led_delay_)
@@ -374,16 +382,41 @@ void flash_led(unsigned int times, unsigned int brightness_divisor, unsigned int
 
 //********************************************************************//
 
+void send_yamaha_ir_signal(char codebyte)
+{
+  unsigned long int code = codebyte & 0xFF;
+  code <<= 8;
+  code |= (0xff ^ codebyte) & 0xFF;
+  code |= YAMAHA_CODE_BASE;
+  
+  //irsend changes PWM Timer Frequency among other things
+  //.. doesn't go well with PWM output using the same timer
+  //.. thus we just set output to 255 so whatever frequency is used, led is off for the duration
+  unsigned int flash_prev_selected = flash_led_selected_; //save prev. selected leds
+  flash_led_selected_ &= !(1 << BLUELED_PWM_PIN); //prevent calculate_led_level() from setting blueled
+  analogWrite(BLUELED_PWM_PIN,255); // switch led off
+
+  irsend.sendNEC(code,YAMAHA_CODE_BITS);
+
+  analogWrite(BLUELED_PWM_PIN,255); // switch off led again to be sure
+  flash_led_selected_ = flash_prev_selected;  //restore led settings for calculate_led_level()
+                                      //is actually not necessary, since we are not multitasking/using interrupts, but just to be sure in case this might change
+
+  Serial.println("Ok");
+}
+
+//********************************************************************//
+
 void setup()
 {
   pinMode(RF_DATA_OUT_PIN, OUTPUT);
   digitalWrite(RF_DATA_OUT_PIN, HIGH);
   pinMode(IR_MOVEMENT_PIN, INPUT);      // set pin to input
-  digitalWrite(IR_MOVEMENT_PIN, LOW);  // turn off pullup resistors  
+  digitalWrite(IR_MOVEMENT_PIN, LOW);  // turn off pulldown resistors  
   pinMode(PANIC_BUTTON_PIN, INPUT);      // set pin to input
-  digitalWrite(PANIC_BUTTON_PIN, HIGH);  // turn on pullup resistors 
-  analogWrite(BLUELED_PWM_PIN,0);
-  analogWrite(BLUELED2_PWM_PIN,255); //pwm sink(-) instead of pwm + (better for mosfets)
+  digitalWrite(PANIC_BUTTON_PIN, LOW);  // turn on pulldown resistors 
+  analogWrite(PANICLED_PWM_PIN,255);
+  analogWrite(BLUELED_PWM_PIN,255); //pwm sink(-) instead of pwm + (better for mosfets)
   pinMode(IRREMOTE_SEND_PIN, OUTPUT);
   digitalWrite(IRREMOTE_SEND_PIN, HIGH);
   
@@ -419,13 +452,13 @@ void loop()
 
   if (pb_time < PB_TRESHOLD)
     pb_time++;
-  pb_state=(digitalRead(PANIC_BUTTON_PIN) == LOW);
+  pb_state=(digitalRead(PANIC_BUTTON_PIN) == HIGH);
   
   if (ir_time == 0)
   {
     if (ir_count >= IR_TRESHOLD)
     {
-      flash_led(1,8,1);
+      flash_led(1, 8, 1, (1<<BLUELED_PWM_PIN) );
       Serial.println("movement");
     }
     ir_time=IR_SAMPLE_DURATION;
@@ -438,7 +471,7 @@ void loop()
     {   
       pb_postth_state=1;
       Serial.println("PanicButton");
-      flash_led(7,1,2);
+      flash_led(14, 1, 2, (1<<BLUELED_PWM_PIN)|(1<<PANICLED_PWM_PIN) );
     }
     else if (!pb_state)
       pb_postth_state=0;
@@ -450,7 +483,7 @@ void loop()
   }
   
   updateLightLevel(PHOTO_ANALOGPIN);
-  calculate_led_level(BLUELED_PWM_PIN);
+  calculate_led_level();
   check_frame_done();
   
   if(Serial.available()) {
@@ -501,8 +534,10 @@ void loop()
       sensorEchoCommand(command);
       printLightLevel();
     }
+    else if (command == '^')
+      flash_led(1, 2, 1, (1 << PANICLED_PWM_PIN));
     else if (command == '0')
-      send_yamaha_ir_signal(YAMAHA_POWER_OFF);    
+      send_yamaha_ir_signal(YAMAHA_POWER_OFF);
     else if (command == '1')
       send_yamaha_ir_signal(YAMAHA_POWER_TOGGLE);
     else if (command == '2')
@@ -520,29 +555,31 @@ void loop()
     else if (command == '8')
       send_yamaha_ir_signal(YAMAHA_MENU);
     else if (command == '+')
-      send_yamaha_ir_signal(YAMAHA_PLUS);    
+      send_yamaha_ir_signal(YAMAHA_PLUS);
     else if (command == '-')
-      send_yamaha_ir_signal(YAMAHA_MINUS);    
-    else if (command == '§')
-      send_yamaha_ir_signal(YAMAHA_TEST);    
+      send_yamaha_ir_signal(YAMAHA_MINUS);
+    else if (command == 0xa7) // §
+      send_yamaha_ir_signal(YAMAHA_TEST);
     else if (command == '$')
-      send_yamaha_ir_signal(YAMAHA_TIME_LEVEL);    
+      send_yamaha_ir_signal(YAMAHA_TIME_LEVEL);
     else if (command == '%')
-      send_yamaha_ir_signal(YAMAHA_EFFECT_TOGGLE);    
+      send_yamaha_ir_signal(YAMAHA_EFFECT_TOGGLE);
     else if (command == '&')
-      send_yamaha_ir_signal(YAMAHA_PRG_DOWN);    
+      send_yamaha_ir_signal(YAMAHA_PRG_DOWN);
     else if (command == '/')
-      send_yamaha_ir_signal(YAMAHA_PRG_UP);    
+      send_yamaha_ir_signal(YAMAHA_PRG_UP);
     else if (command == '(')
-      send_yamaha_ir_signal(YAMAHA_TUNER_PLUS);    
+      send_yamaha_ir_signal(YAMAHA_TUNER_PLUS);
+    else if (command == '[')
+      send_yamaha_ir_signal(YAMAHA_TUNER_MINUS);
     else if (command == ')')
-      send_yamaha_ir_signal(YAMAHA_TUNER_ABCDE);    
+      send_yamaha_ir_signal(YAMAHA_TUNER_ABCDE);
     else if (command == '9')
-      send_yamaha_ir_signal(YAMAHA_TAPE);    
+      send_yamaha_ir_signal(YAMAHA_TAPE);
     else if (command == '?')
-      send_yamaha_ir_signal(YAMAHA_VCR);    
+      send_yamaha_ir_signal(YAMAHA_VCR);
     else if (command == '=')
-      send_yamaha_ir_signal(YAMAHA_EXT51DEC);    
+      send_yamaha_ir_signal(YAMAHA_EXT51DEC);
     else
       Serial.println("Error: unknown command");
   }