Light Controller

PIC24FJ64GB002 Light and Power Strip Controller

This is a take off from my switched power strip.  I have used the remote control power strip a few times but wanted to have something I could dedicate to my light box and the lights I use around it.  These lights are bright and get hot very quickly.  I find myself leaving them on and thought it would be good to have a timer on them so I wouldn’t forget to turn them off and burn up my light box.

I started with a power strip and wired in parallel with the switch.  This allows me to use a relay to activate the switch.  I hooked up a button to the PIC24FJ64GB002 so that I could activate the lights with the simple press of a button.  I wanted the lights to stay on for about 30 seconds but on some trial and error I settled on a bit less time than that about 20 seconds seems to be just about right.

I used the library you can find here to implement the timer.  It was a simple matter of scanning the switch with a simple delay then when a button is detected enabling the relay and also a delay for the 20 seconds.  Once the 20 seconds has expired another routine is started that turns off the lights and allows the scanning of the button to start again.

Here is a schematic of what I came up with.

Light Control Schematic

Light Control Schematic

You can see the very simple additions to control the lights.  There is the relay attached to an NPN type transistor.  I actually used a TIP120 type darlington as I had a bunch of those laying around.  I believe the NPN would work just as well.

The push button is attached to an input pin with a pull up so that the switch can pull the pin low to indicate a button press to the microcontroller.  You have to make sure that you debounce the switch as there will be many make and break cases with just one button press.  When I was first starting in electronics at the University of Utah our first lab was to count the number of bounces of a switch.  I counted over a 1000 bounces before the switch settled down.  That seems like a lot.  I guess the switches they were using for the lab were especially bouncy.  But, it was a lesson I never forgot.  There is not only the bounce on the way down there is bounce on the way up.  So, both directions need to be debounced for proper switch handling.

/******************************************************************************
 * Module:        main USB test module
 *
 * Overview:      Main program entry point.  This was written to prove the USB
 *   stack.
 *
 * Owner:         Kim Mansfield
 *
 * Copyright:     KMI Technology @ 2013
 *
 * Note:          None
 *
 *****************************************************************************/

#include "./USB/usb.h"
#include "./USB/usb_function_cdc.h"

#include "HardwareProfile.h"
#include "ssrtos.h"
#include "pins.h"

extern int numBytesRead;
extern char USB_In_Buffer[256];
extern char USB_Out_Buffer[64];
extern unsigned char NextUSBOut;

/** CONFIGURATION **************************************************/
_CONFIG1(JTAGEN_OFF & GCP_OFF & GWRP_OFF & ICS_PGx1 & FWDTEN_OFF & WINDIS_OFF & FWPSA_PR32 & WDTPS_PS8192)
_CONFIG2(IESO_OFF & FNOSC_FRCPLL & OSCIOFNC_ON & POSCMOD_NONE & PLL96MHZ_ON & PLLDIV_DIV2 & FCKSM_CSDCMD & IOL1WAY_OFF)
_CONFIG3(WPFP_WPFP0 & SOSCSEL_IO & WUTSEL_FST & WPDIS_WPDIS & WPCFG_WPCFGDIS & WPEND_WPENDMEM)
_CONFIG4(DSWDTPS_DSWDTPS3 & DSWDTOSC_LPRC & RTCOSC_LPRC & DSBOREN_OFF & DSWDTEN_OFF)

int charToSend;

/******************************************************************************
 * Function:        void handUSB(void)
 *
 * parameters:      None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        This routine handles input from the USB port.
 * 
 * Note:            None
 *****************************************************************************/
void
handUSB(void)
{
#if 0
   if (numBytesRead > 0)
   {
      if (USB_In_Buffer[0] == 'B')
      {
         strcpy(USB_Out_Buffer,"This is a B\r\n");
         NextUSBOut = strlen(USB_Out_Buffer);
      }
      else
      {
      strncpy(USB_Out_Buffer,USB_In_Buffer,numBytesRead);
      NextUSBOut = numBytesRead;
      }
      numBytesRead = 0;
   }
   queueUSB(handUSB);
#endif
   if (numBytesRead > 0)
   {
     charToSend = USB_In_Buffer[0];
     USB_Out_Buffer[0] = charToSend;
     USB_Out_Buffer[1] = 0;
     strcat(USB_Out_Buffer," = ");
     //strcat(USB_Out_Buffer,mChars[charToSend-'A']);
     NextUSBOut = strlen(USB_Out_Buffer);
     numBytesRead = 0;
   }
   queueUSB(handUSB);
}

int pinState;
int deCount = 0;
int kdelayState = 0;

/******************************************************************************
 * Function:        void deOff(void)
 *
 * parameters:      None
 *
 * Output:          None
 *
 * Side Effects:    turns off the relay.
 *
 * Overview:        This is the routine that turns off the relay and allows
 *        the other routine to start scanning the button again.
 * 
 * Note:            None
 *****************************************************************************/
void
deOff(void)
{
   if (deCount)
   {
      deCount--;
      delayMS(deOff,1000);
   }
   else
   {
      digitalWrite(PIN16,LOW);
      kdelayState = 0;
   }
}

/******************************************************************************
 * Function:        void kdelay(void)
 *
 * parameters:      None
 *
 * Output:          None
 *
 * Side Effects:    Starts another routine to turn of the lights.
 *
 * Overview:        This is the routine that scans the button for a press.  
 *        when a button press is detected another delay routine is started, 
 *        the relay is turned on, and we switch states so another button 
 *        bounce won't start another delay routine again.  I had this very 
 *        problem.
 * 
 * Note:            None
 *****************************************************************************/
void
kdelay(void)
{

   switch (kdelayState)
   {
      case 0:
         if ((PORTB & 0x8000) == 0)
         {
            digitalWrite(PIN16,HIGH);
            delayMS(deOff,2000);
            deCount = 10;
            kdelayState = 1;
         }
         break;
      case 1:
         break;
   }
   delayMS(kdelay,10);
}

/******************************************************************************
 * Function:        void main(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Main program entry point.
 *
 * Note:            None
 *****************************************************************************/
int main(void)
{   
   initializeSystem();
   // TODO need to fix these names not good.  They are too close.
   InitializeSystem();

   PORTB = 0;
   TRISB = 0x00FF;

   pinMode(PIN16,OUTPUT);
   pinMode(PIN26,INPUT);

   queueUSB(handUSB);

   delayMS(kdelay,5);

   while(1)
   {
      runNext();
   }//end while
}//end main

There is the code.