Go Down

Topic: Code doesn't jump out of loop? (Read 474 times) previous topic - next topic

inboxjason

Hi everyone,
Got a problem that I suspect is a simple one to fix, but it's got me stumped. The code below is for a room automation system I'm working on. The problem I'm running into is that as soon as
loop() calls a function, the function loops repeatedly, there is no exit from the function. I was using a software reset to exit the loop but this seems silly...
There is some sleep code which is commented out at the moment, it serves no purpose just yet. There is also a Light Dependent Resistor which is not in use yet.
If anyone could point me in the right direction/give me some coding tips, I'd be much obliged! This is my first Arduino project that doesn't consist of blinking lights!
Code: [Select]
/*

Jason    26/10/2011
Updated 09/12/2011
LCD + RTC Added
LCD to Display Current Time/Date/
              AVR last selected (XBMC, XBOX 360)
              Current Light Level?
              Temp?

IR to IR Blaster
Takes commands from XBMC remote and
outputs Samsung/Xbox360 IR commands.
Control HomeEasy Sockets
Detect presence in room and turns lights on/off
AKA Universal Remote/Automated room.
Pin Map
D2 - PIR
D3 - IR LED (hard coded)
D4 - 433 Mhz RF
D5 - Green LED/StatusLed
D6 - Red LED
D7 - Amber LED
D8 - IR Receiver
D9 -  LCD PIN_SCE (Chip Select)
D10 - LCD PIN_RESET
D11 - LCD PIN_DC
D12 - LCD PIN_SDIN
D13  -LCD PIN_SCLK

A0 - LDR
A4 - I2C RTC
A5 - I2C RTC
*/

#include <IRremote.h>
#include <IRremoteInt.h>
#include <avr/sleep.h>
#include "PCD8544.h"
#include <Wire.h>
#include "RTClib.h"
#include <HomeEasyAdv.h>


// Setup PIR
const int pirPin = 2;
int pirVal = 0;     // Raw value

// Setup IR
IRsend irsend;
const int RECV_PIN = 8;
IRrecv irrecv(RECV_PIN);
decode_results results;

// Setup RTC
RTC_DS1307 RTC;

// Setup LCD
PCD8544 lcd = PCD8544(13,12,11,9,10);

// Setup 433Mhz RF
#define TXPIN 3
#define RXPIN 4    // This is never used as we only TX. Generates a compiler error w/o pin assignment.
#define REMOTE_ADDRESS 4597902  // Address of the HomeEasy Remote
HomeEasyAdv homeeasy = HomeEasyAdv(RXPIN, TXPIN, REMOTE_ADDRESS );

// Samsung IR Code Array
// These are raw codes copied from remote
unsigned int samKeyZero[68] = {4550,4400,600,1650,600,1600,600,1650,600,500,600,550,600,500,600,500,600,550,600,1600,600,1650,600,1600,600,550,600,500,600,500,600,550,600,500,600,1650,550,550,600,500,600,500,600,1650,600,500,600,550,600,500,600,500,600,1650,600,1650,550,1650,600,500,600,1650,600,1650,600,1600,600};  
unsigned int samSource[68] = {4550,4400,600,1650,600,1600,600,1650,600,500,600,550,600,500,600,500,600,550,600,1600,600,1650,600,1600,600,550,600,500,600,500,600,550,600,500,600,1650,600,500,600,500,600,550,550,550,600,500,600, 500,600,550,600,500,600,1650,600,1600,600,1650,600,1650,550,1650,600,1650,600,1600,600};
unsigned int samDown[68] = { 4500,4350,600,1600,600,1600,600,1650,600,500,600,500,600,500,600,500,600,500,600,1600,600,1650,550,1650,600,500,600,500,600,500,600,500,600,500,600,1600,600,500,600,500,600,550,550,550,550,1650,600,1600,600,500,600,500,600,1600,600,1650,550,1650,600,1600,600,500,600,500,600,1600,600};
unsigned int samKeyTV[68] = {4500,4450,600,1600,600,1650,600,1650,600,500,600,500,600,550,550,550,600,500,600,1650,600,1600,600,1650,600,500,600,550,550,550,600,500,600,500,600,1650,600,1650,600,500,600,1650,600,1600,600,550,600,500,600,500,600,500,600,550,600,1600,600,550,600,500,600,1650,600,1600,600,1650,600};
unsigned int samSelect[68] = {4500,4450,600,1600,600,1650,600,1600,600,550,600,500,600,500,600,550,600,500,600,1600,600,1650,600,1650,600,500,600,500,600,550,600,500,600,500,600,550, 600,500,600,500,600,1650,600,500,600,1650,600,1600,600,550,600,1600,600,1650,600,1650,600,500,600,1600,600,550,600,500,600,1650,600};
unsigned int samPowerOff[68] = {4550,4400,600,1600,650,1600,600,1650,600,500,600,500,650,500,600,500,600,500,600,1650,600,1600,650,1600,600,500,650,500,600,500,600,500,650,500,600,500,600,1600,650,500,600,500,600,500,650,500,600,500,600,500,600,1650,600,500,650,1600,600,1600,600,1650,600,1650,600,1600,650,1600,600};

// Xbox 360 PowerOn Code
unsigned long long OnOff = 0xc800f740cLL;

// XBMC Button ID Codes
long xbmcOne = 1231295254;
long xbmcTwo = 485710105;
long xbmcThree = 4048549466;
long xbmcFour = 1048693617;
long xbmcFive = 2368749434;
long xbmcSix =  959017269;
long xbmcSeven = 226889334;
long xbmcEight = 2408122201;
long xbmcMenu = 168945401;
long xbmcUp = 4004649538;
long xbmcDown = 2684593721;
long xbmcEnter = 3468483545;

// Toggle bit for RC6 Codes
int toggle = 0;

// Status LEDS
int statusLED = 5;
int redLED = 6;
int amberLED = 7;

// Time related vars
const int delay_time = 100;  // Delay for the blink function
int lastSelected = 0; // Last command selected
long currentTime; // Holds timestamp from RTC

void setup()
{
 Serial.begin(9600);
 Serial.println("Serial enabled...");
 irrecv.enableIRIn();          // Start the receiver
 pinMode(TXPIN, OUTPUT);
 pinMode(pirPin, INPUT);
 pinMode(redLED, OUTPUT);
 pinMode(amberLED, OUTPUT);
 pinMode(statusLED, OUTPUT);
 Wire.begin();
 RTC.begin();
 lcd.init();
 lcd.setContrast(60);
 lcd.clear();
//attachInterrupt(0, wakeUp,RISING);  // Attach rising as PIR goes LOW-HIGH
}

void loop()
{
 pirVal = digitalRead(pirPin);
 if (pirVal == HIGH)
 {
  // printTime();
   digitalWrite(statusLED, HIGH);     // Turn on status so we know sending ok
   digitalWrite(amberLED, LOW);    
   if (irrecv.decode(&results))
   {
     digitalWrite(statusLED, LOW);    //turn off status led so we know not to re send  
     Serial.println(results.value,DEC);
     blinkLED(200, amberLED);   // Blink amber led to show IR recv
   
     if (results.value == xbmcOne)
     {
       switchToXBMCVideos();
       Serial.println("XBMC Videos");
       lastSelected = 1;
     }
   
     if (results.value == xbmcTwo)
     {
       sendOnOff();
       Serial.println("XBMC Movies");
       lastSelected = 2;

     }
 
     if (results.value == xbmcThree)
     {
       sendOnOff();
       switchToXBox360();
       Serial.println("XBox 360");
       lastSelected = 3;
     }
 
     if (results.value == xbmcFour)
     {
       HEsocketOn(0);
       HEsocketOn(1);
       Serial.println("Lights on");
       lastSelected = 4;
     }
   
     if (results.value == xbmcFive)
     {
       HEsocketOff(0);
       HEsocketOff(1);
       Serial.println("Lights off");
       lastSelected = 5;
     }
 
     if (results.value == xbmcSix)
     {
       // Unused button!
     }
 
     if (results.value == xbmcSeven)
     {
        HEsocketOn(2);
        Serial.println("Xbox On");
        lastSelected = 7;
     }

     if (results.value == xbmcEight)
     {
       HEsocketOff(2);
       Serial.println("Xbox Off");
       lastSelected = 8;
     }      
   }
 }

 else
 {
   digitalWrite(statusLED, LOW);   // No one in front of PIR
   Serial.println("ELSE");  
   DateTime now = RTC.now();
   currentTime = now.unixtime();  // Get timestamp
   if (currentTime >= currentTime + 300)  // 300s = 5 mins
    {switchAllOff;}
 }
}


/*
void(* resetFunc) (void) = 0;  // Soft reset function jmp to add

// This func executes on return from sleep.
void wakeUp()  
{
 resetFunc();
}


   


Thanks!!

inboxjason

Part two on the code...
Code: [Select]
void sleepNow()
{
 set_sleep_mode(SLEEP_MODE_PWR_DOWN);  // Set sleep mode
 sleep_enable();    // Prepare to sleep
 attachInterrupt(0,wakeUp,RISING);
 sleep_mode();  // Actually sleep!
 sleep_disable();  // Return from sleep here!
 detachInterrupt(0);
 delay(75);
}

*/


// Blinking on data xfer
void blinkLED(int duration, int pin)
{
 pinMode(pin,OUTPUT);
 digitalWrite(pin, HIGH);
 delay(duration);
 digitalWrite(pin, LOW);
}

// Send onoff code to Xbox 360
void sendOnOff() {
 if (toggle == 0) {
   irsend.sendRC6(OnOff, 36);
 }
 else {
   irsend.sendRC6(OnOff ^ 0x8000, 36);
 }
 toggle = 1 - toggle;
}

// Sends simulated key presses to Samsung TV
void switchToXBMCVideos()
{
 blinkLED(100,redLED);
 irsend.sendRaw(samKeyZero,68,38);
 delay(delay_time);
 blinkLED(100,redLED);
 irsend.sendRaw(samKeyTV,68,38);
 delay(delay_time);
 blinkLED(100,redLED);
 irsend.sendRaw(samSource,68,38);
 delay(delay_time);
 blinkLED(100,redLED);
 irsend.sendRaw(samDown,68,38);
 delay(delay_time);
 blinkLED(100,redLED);  
 irsend.sendRaw(samDown,68,38);
 delay(delay_time);
 blinkLED(100,redLED);
 irsend.sendRaw(samSelect,68,38);

}


// Sends simulated key presses to Samsung TV
void switchToXBox360()
{
 blinkLED(100,redLED);
 irsend.sendRaw(samKeyZero,68,38);
 delay(delay_time);
 blinkLED(100,redLED);
 irsend.sendRaw(samKeyTV,68,38);
 delay(delay_time);
 blinkLED(100,redLED);
 irsend.sendRaw(samSource,68,38);
 delay(delay_time);
 blinkLED(100,redLED);
 irsend.sendRaw(samDown,68,38);
 delay(delay_time);
 blinkLED(100,redLED);  
 irsend.sendRaw(samDown,68,38);
 delay(delay_time);
 blinkLED(100,redLED);
 irsend.sendRaw(samDown,68,38);
 delay(delay_time);
 blinkLED(100,redLED);
 irsend.sendRaw(samDown,68,38);
 delay(delay_time);
 blinkLED(100,redLED);
 irsend.sendRaw(samSelect,68,38);
}

// Turn everything off!
void switchAllOff()
{
 blinkLED(100,redLED);
 irsend.sendRaw(samKeyTV,68,38);
 delay(delay_time);
 blinkLED(100,redLED);
 irsend.sendRaw(samPowerOff,68,38);
 HEsocketOff(0);
 HEsocketOff(1);
 HEsocketOff(3);
}

void printTime()
{
 DateTime now = RTC.now();
 lcd.setCursor(15, 0);
 lcd.print(now.year(), DEC);
 lcd.print('/');
 lcd.print(now.month(), DEC);
 lcd.print('/');
 lcd.print(now.day(), DEC);
 lcd.print(' ');
 lcd.setCursor(15, 10);
 lcd.print(now.hour(), DEC);
 lcd.print(':');
 lcd.print(now.minute(), DEC);
 lcd.print(':');
 lcd.print(now.second(), DEC);
 lcd.display();
}

void HEsocketOn(int socketNo)
{
 for (int a=0; a<=5; a++)
     {homeeasy.on(socketNo);}
 lcd.setCursor(15,10);
 lcd.print("Socket No ");
 lcd.print(socketNo);
 lcd.print(" on");
}

void HEsocketOff(int socketNo)
{
 for (int a=0; a<=5; a++)
     {homeeasy.off(socketNo);}
 lcd.setCursor(15,10);
 lcd.print("Socket No ");
 lcd.print(socketNo);
 lcd.print(" off");
}

PaulS

Code: [Select]
     {switchAllOff;}
What do you think this is supposed to do?

PeterH

Are you sure your decode function is working properly?

If it failed, but returned a value you interpret as success (without overwiring the buffer you passed in to receive the results) then you would process that result again and again - giving the symptoms you describe.

Suggest you stick some print statements in showing when it thinks it has received something, when it thinks it has successfully decoded it and what it decodes to, and see whether the logic to handle inputs is detecting your commands properly.
I only provide help via the forum - please do not contact me for private consultancy.

inboxjason

It was indeed the decode function, I forgot to call
Code: [Select]
irrecv.resume();
With that in place, the receiver goes back to listening for the next command. Just realised I can't have the LCD display and capture codes, so the remote side of things is going to have to become interrupt driven. This is new to me, but should keep me busy tonight.
Thanks for your quick replies!

Louis Davis

I believe you need to call irrecv.resume(); after you have decoded the message.
This may clear the result, so that you will not continue to get the same result over and over again.

Go Up