Show Posts
Pages: [1] 2 3
1  Topics / Home Automation and Networked Objects / Re: Ever use a Fairchild MID400 AC line sensing opto? on: April 03, 2014, 06:36:39 pm
Thanks polyglot.

Yeah, finally wrapped my head around it. For some reason the datasheet was confusing me. Any way in case anyone else is wondering and is confused by the datasheet, to figure out the input resistor you simply use this formula:

InputResistor = (InputVoltage - LED-FowardVoltage) / LEDCurrent

The LED requires a minimum of 4mA to trigger an "on" state on the output and can go as high as 25mA.

So in my case, assuming that I want to draw as little current as possible I'd use a 5.6k resistor:  (24v - 1.5v) / 0.004. At 4mA the resistor would have to dissipate 0.096 watts (24v x 0.004 Amps = 0.096 watts) so a 1/4 watt resistor would be more than ok.

It's my understanding that HVAC systems can be sensitive to foreign loads so it's a good idea to keep the draw as little as possible.

 
2  Topics / Home Automation and Networked Objects / Re: Ever use a Fairchild MID400 AC line sensing opto? on: April 02, 2014, 06:41:04 pm
@JohnHoward

Hey John, I'm working on something that looks similar to your project but less involved. I simply want to detect when the heat has been turned on. I've already checked and I can tap into the W line that goes to 24v when the thermostat calls for heat and goes back to 0 when the thermostat ends the call for heat.

Like you I've been trying to figure out a way to get the 24v AC from the furnace to the Arduino and came across the MID400. However, the datasheet has my head spinning a bit. I've looked at two schematics that you've posted and have some questions if you don't mind...

In one of your schematics you have a 10k resistor on the AC side and in the other you have a 2.2k resistor. Based on looking at the data sheets I've calculated that a 5.6k resistor would be needed for 24v. Can you tell me how you derived your values and why the change between schematics?

thanks
3  Using Arduino / Project Guidance / Re: LED Strip project for my son to be born Feb 2nd. on: December 18, 2013, 04:03:55 pm
Sounds like you want to study up on the infra-red libraries for the Arduino so you can emulate the remote controls with a strategically placed IR LED.


Good idea. I made an IR controlled car using an Apple remote and Ken Shirrff's IR library.

http://www.righto.com/2009/08/multi-protocol-infrared-remote-library.html

Using the library you should be able to decode the existing remotes codes. Once you know the codes it's easy to play them back using the Arduino.
4  Using Arduino / Project Guidance / Re: Mailbox Notifier Odd Behavior on: December 18, 2013, 03:59:06 pm
When it was colder I did check the voltage and current draw and it was fine. The issue also occurred when thing warmed up, well above freeing but still cold. The charger also monitors the temperature to insure the batter is not charged if it's too cold or hot.

Perhaps worth checking again though.
5  Using Arduino / Project Guidance / Re: LED Strip project for my son to be born Feb 2nd. on: December 18, 2013, 02:29:20 pm
You realize that the lights you linked to already have a controller built in, even has a remote to change the colors!

What do you want the Arduino to do?
6  Using Arduino / Project Guidance / Re: Mailbox Notifier Odd Behavior on: December 18, 2013, 02:15:46 pm
KISS.

I re-wrote it last night, hopefully this is easier to follow. 

In any case, since you didn't think that the coding was the fault of the issues I was seeing I went ahead and swapped out the pro mini for another; grasping at this point. I'll have to wait till later tonight or tomorrow morning to see if the issue pops up again since it spent the night inside.   

Thanks again.

Code:
#include <avr/sleep.h>

// PIN Names
int DeliverSW = 2;
int RetrieveSW = 3;
int XBPower = 4;
int NotifyLED1 = 5;
int NotifyLED2 = 6;
int DomeLED = 7;

// Vars
bool delivery = false;
int transmitCount = 0;
int timesToTransmit = 10; // Number of times we will send out the ON or OFF signal out for the house notification. This can be reduced if the distance/interferace of the enviornmen is low
int XBeeWakeupDelay = 20000; // Number of milliseconds we wait after waking the XBee before using it
int XBeeTransmitDelay = 1500; // Number of milliseconds we wait between transmitions

void setup() {
  // Set PINs as inputs or outputs
  pinMode(DeliverSW, INPUT);
  pinMode(RetrieveSW, INPUT);
  pinMode(XBPower, OUTPUT);
  pinMode(NotifyLED1, OUTPUT);
  pinMode(NotifyLED2, OUTPUT);
  pinMode(DomeLED, OUTPUT);
 
  // Enable internal resistors by setting the PINs as HIGH. This is so we don't have to use pesky external resistors
  digitalWrite(DeliverSW, HIGH);
  digitalWrite(RetrieveSW, HIGH);
 
  // Start your serial engines!
  Serial.begin(9600); 
}

void loop() {
  digitalWrite(XBPower, HIGH); // Put the XBee to sleep
  delay(1000); // wait a second and then go to sleep
  F_sleep();
}

void F_sleep() {
  attachInterrupt(0, F_Interrupt, RISING); // Attach the interrupt so that we can wake up when mail is delivered
  attachInterrupt(1, F_Interrupt, RISING); // Attach the interrupt so that we can wake up when mail is retrieved
 
  delay(100); // Slight delay for sanity
 
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Most power savings in this mode
  sleep_mode(); // Go to sleep
  sleep_disable(); // When woken up will continue to process from this point
 
  F_process(); // Figure out what switch woke up the Arduino and act accordingly
}
 
void F_Interrupt() {
}

void F_process() {
  if (digitalRead(DeliverSW) == HIGH && delivery == false) {
    digitalWrite(XBPower, LOW); // Turn the radio on
    delay(XBeeWakeupDelay); // Give the radio some time to settle after waking up
   
    // For the sake of making sure the house notification gets its ON signal we send the ON command out, wait 1.5 seconds and then send it out again until transmitCount is equal to timesToTransmit
    for (int t=0; t != timesToTransmit; t++){
      Serial.println("1"); // Send a character out the serial to turn on the house notification
      delay(XBeeTransmitDelay); // Give some time for the transmition to end before we send the next one
    }
   
    digitalWrite(NotifyLED1, HIGH); // Turn the external notification LEDs on
    digitalWrite(NotifyLED2, HIGH); // Turn the external notification LEDs on
   
    delivery = true;
}
 
  if (digitalRead(RetrieveSW) == HIGH && delivery == true) {
    digitalWrite(NotifyLED1, LOW); // Turn off the external notification LEDs
    digitalWrite(NotifyLED2, LOW); // Turn off the external notification LEDs
   
    // Turn on the dome LED on until the retrive door is closed so we can see inside the mailbox if it's dark outside
    while (digitalRead(RetrieveSW) == HIGH) {
      digitalWrite(DomeLED, HIGH);
    }
   
    digitalWrite(DomeLED, LOW); // Turn the dome LED off
   
    digitalWrite(XBPower, LOW); // Turn the radio on
    delay(XBeeWakeupDelay); // Give the radio some time to settle after waking up before doing anything with it
   
    // For the sake of making sure the house notification gets its OFF signal we send the OFF command out, wait 1.5 seconds and then send it out again until transmitCount is equal to timesToTransmit
    for (int t=0; t != timesToTransmit; t++){
      Serial.println("0"); // Send a character out the serial to turn on the house notification
      delay(XBeeTransmitDelay); // Give some time for the transmition to end before we send the next one
    }
   
    delivery = false;
  }
}
7  Using Arduino / Project Guidance / Re: Mailbox Notifier Odd Behavior on: December 17, 2013, 07:31:59 pm
Now that I look at it you are right about the state machine... probably to much for this but I used on in another project and just like the flow of it.

Yes, the delivery var is used to keep the delivery function from triggering more than once after mail has been delivered and to also only start the retrieval function if mail has been delivered.

I struggled with detaching the interrupts... I was not sure when or where to do it. Examples showed you detaching the interrupts in the interrupt function but doing that cause them to only work once. Glad to know my feeling was right, that in this case it's not necessary.
 
I suppose your issue with transmitCount is a matter of taste. I see how a for loop could be more elegant and eliminate code... but either would work.

Thanks for taking a look
8  Using Arduino / Project Guidance / Re: Mailbox Notifier Odd Behavior on: December 17, 2013, 01:14:04 pm
Ok, I'll explain the what is expected to happen at each step...

Mail is delivered:

Delivery door is opened, triggering the interrupt, waking the Arduino. The Arduino sees that it's the delivery door that was triggered and runs the deliver function.

The XBee is woken up and the Arduino waits for 15 seconds before doing anything else.

The Arduino then sends a 1 out the serial which the XBee then transmits to turn the house light on. Because I am near the limit of the Xbee range I have it set to transmit the 1, wait 1.5 seconds and then transmits it again, it does this 20 times to insure that the signal is received. I use the var transmitCount to count how many times the signal was sent out when it reaches 20, we stop transmitting.

The external notification LEDs are turned on.

The transmitCount is then reset to 0 so that it can be used during the retrieve function.

This:

Code:
else if (delivery == true) {
    state = S_sleep;
  }

was put there to put the Arduino back to sleep if the delivery door was opened after delivery was already detected. You are correct that this would be redundant if we were not concerned with the Arduino sleeping. If this was not there the interrupt would wake the Arduino go to the deliver function and then sit there, never going back to sleep.

The delivery var is set to true so we know to run the retrieve function if the retrieval door is opened.

Mail is delivered:

Retrieval door is opened, triggering the interrupt, waking the Arduino. The Arduino sees that it's the retrieval  door that was triggered and runs the retrieve function.

External LEDs are turned off.

Dome light is turned on and stays on (we loop here) until the retrieval door is closed.

Retrieval door is closed so we turn the dome LED off, turn the XBee on, wait 15 seconds and then transmit.

The transmit sequence is the same as during the delivery - only this time we send a 0 to turn off the light. This is why transmitCount was reset to 0 so we can use the var here to count how many time we've transmitted.

After the transmit sequence we reset transmitCount set delivery to false and then go back to sleep.

Here, the use of the boolean  delivery is used to detect if the delivery sequence has run. If it has not we can just go back to sleep if the retrieval door is opened.
9  Using Arduino / Project Guidance / Mailbox Notifier Odd Behavior on: December 17, 2013, 12:05:22 pm
Apologies, this is going to be a long post.

I am using an Arduino Pro Mini in conjunction with the Adafruit solar charger and Minty Boost for power. I have a 3.7V 4400mAh  Li-ion battery for power when solar is not available.  I am using an XBee (series 1) to send a character (0 or 1) to turn a light in my house on when the mail is delivered. There are also two LEDs mounted to the outside of the mailbox for external notification. The electronics are housed in an IP65 enclosure which is mounted inside the mailbox.

In order to save power I have it programmed so the Arduino puts the XBee to sleep when it's not in use and then the Arduino puts itself to sleep. The Arduino is woken up via external interrupt, it then wakes the XBee, runs through the program and then everything goes back to sleep. I use two interrupts, one for delivery and one for retrieval, both are triggered by a respective reed switch.

On the bench everything works perfectly. Even when I first get the mailbox outside and mounted on the post it all works perfectly. I first noticed issues when I was testing and the temperature started to drop. We were getting to sub-freezing temps. At these temps I found that things didn't work quite as expected - the delivery would almost always work, but the retrieval would almost always fail. Timing also seemed to be off, the XBee would not stay awake as long as it should. Sometimes it would wake up and then immediately go off. Other times it would stay on for much longer than it should.

I'm certain the issues I'm having are related to the cold temps. because if I played with it enough outside, ran through the delivery and retrieval sequences enough times to get things warmed up, then it would start to work. If I bring the mailbox back inside and give it a bit to warm up, everything starts to work again too. However, I'm not approaching temps below what the components are rated for. The lowest temps it's been in are 4F and almost all of the components are rated to -40C. And now the temps have warmed up to the mid to high 30s (F) but I'm still seeing the issue.

The only thing that I can think of is that because the Arduino and XBee both sleep most of the time and draw so little power that they are able to get really cold and that then affects the operation. My feeling is that the crystal on the Arduino is getting to cold which is why I'm seeing the timing issues. Still the crystal is rated to -40C... I've also seen various Arduino projects that relegate it to being outside and have not heard any issues reported. The only difference is all those projects have the Arduino in a cyclic wake-sleep cycle which, I imagine, would keep the Arduino warmer than it would be just being asleep.

Anyway, just to be sure I'm hoping that someone could look over my code to insure that I don't have anything in there that would be inducing the this behavior.

Thanks.

Code:
/**********************************************************************************************************************
Mailbox Notifier - Mailbox Side

This sketch was written to work as a Snail mail box delivery notification system. It uses to LEDs mounted to the mailbox
as local (to the mailbox) delivery notifications. It also sends out a serial character via a connected XBee modem. When
the receiving XBee (set in a remote location like in your house) receives the character it either turns an indicator
light on or off.

For more information see - http://adambyers.com/2013/11/mailbox-notifier/ or ping adam@adambyers.com

All code (except external libraries and third party code) is published under the MIT License.

**********************************************************************************************************************/

#include <avr/sleep.h>

// States
#define S_sleep 1
#define S_process 2
#define S_deliver 3
#define S_retrieve 4

// Default start up state
int state = S_sleep;

// PIN Names
int DeliverSW = 2;
int RetrieveSW = 3;
int XBPower = 4;
int NotifyLED1 = 5;
int NotifyLED2 = 6;
int DomeLED = 7;

// Vars
bool delivery = false;
int transmitCount = 0;
int timesToTransmit = 20; // Number of times we will send out the ON or OFF signal out for the house notification. This can be reduced if the distance/interferace of the enviornmen is low
int XBeeWakeupDelay = 15000; // Number of milliseconds we wait after waking the XBee before using it
int XBeeTransmitDelay = 1500; // Number of milliseconds we wait between transmitions

void setup() {
  // Set PINs as inputs or outputs
  pinMode(DeliverSW, INPUT);
  pinMode(RetrieveSW, INPUT);
  pinMode(XBPower, OUTPUT);
  pinMode(NotifyLED1, OUTPUT);
  pinMode(NotifyLED2, OUTPUT);
  pinMode(DomeLED, OUTPUT);
 
  // Enable internal resistors by setting the PINs as HIGH. This is so we don't have to use pesky external resistors
  digitalWrite(DeliverSW, HIGH);
  digitalWrite(RetrieveSW, HIGH);
 
  // Start your serial engines!
  Serial.begin(9600); 
}

void loop() {
  switch(state) {
   
    case S_sleep:
      F_SleepyTime();
    break;
 
    case S_process:
      F_process();
    break;
 
    case S_deliver:
      F_deliver();
    break;
   
    case S_retrieve:
      F_retrieve();
    break;
  }
}

void F_SleepyTime() {
  attachInterrupt(0, F_Interrupt, RISING); // Attach the interrupt so that we can wake up when mail is delivered
  attachInterrupt(1, F_Interrupt, RISING); // Attach the interrupt so that we can wake up when mail is retrieved
 
  digitalWrite(XBPower, HIGH); // Put the XBee to sleep
 
  delay(100); // Slight delay for sanity
 
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Most power savings in this mode
 
  sleep_enable(); // Enable sleep
 
  sleep_mode(); // Go to sleep
 
  sleep_disable(); // When woken up will continue to process from this point
 
  state = S_process; // Figure out what switch woke up the Arduino and act accordingly
}

void F_Interrupt() {
// Empty funciton for interrupt
}

void F_process() {
  // Functionally unnecessary but for good mesure we detach the interrupts while we are not using them
  detachInterrupt(0);
  detachInterrupt(1);
 
  if (digitalRead(DeliverSW) == HIGH){
    state = S_deliver;
  }
 
  if (digitalRead(RetrieveSW) == HIGH) {
    state = S_retrieve;
  }
}
 
void F_deliver() { 
  if (delivery == false) {
    digitalWrite(XBPower, LOW); // Turn the radio on
    delay(XBeeWakeupDelay); // Give the radio some time to settle after waking up
   
    // For the sake of making sure the house notification gets its ON signal we send the ON command out, wait 1.5 seconds and then send it out again until transmitCount is equal to timesToTransmit
    while(transmitCount != timesToTransmit){ 
      Serial.println("1"); // Send a character out the serial to turn on the house notification
      delay(XBeeTransmitDelay); // Give some time for the transmition to end before we send the next one
      transmitCount ++;
    }
   
    // Turn the external notification LEDs on
    digitalWrite(NotifyLED1, HIGH);
    digitalWrite(NotifyLED2, HIGH);
   
    transmitCount = 0; // Reset
    delivery = true;
    state = S_sleep;
  }
 
  // To make sure we conserve power we just go right back to sleep if the delevery door is opened after we have already detcted delivery
  else if (delivery == true) {
    state = S_sleep;
  }
}

void F_retrieve() {
  if (delivery == true) {
    // Turn off the external notification LEDs
    digitalWrite(NotifyLED1, LOW);
    digitalWrite(NotifyLED2, LOW);
   
    // Turn on the dome LED on untill the retrive door is closed so we can see inside the mailbox if it's dark outside
    while (digitalRead(RetrieveSW) == HIGH) {
      digitalWrite(DomeLED, HIGH);
    }
   
    digitalWrite(DomeLED, LOW); // Turn the dome LED off
   
    digitalWrite(XBPower, LOW); // Turn the radio on
    delay(XBeeWakeupDelay); // Give the radio some time to settle after waking up before doing anything with it
   
    // For the sake of making sure the house notification gets its OFF signal we send the OFF command out, wait 1.5 seconds and then send it out again until transmitCount is equal to timesToTransmit
    while(transmitCount != timesToTransmit){ 
      Serial.println("0"); // Send a character out the serial to turn off the house notification
      delay(XBeeTransmitDelay);
      transmitCount ++;
    }
   
    transmitCount = 0; // Reset
    delivery = false;
    state = S_sleep;
  }

  // To make sure we conserve power we just go right back to sleep if the the retrive door is opened when a delivery has not been detected
  else if (delivery == false) {
    state = S_sleep;
  }
}
10  Using Arduino / Project Guidance / Re: Help with timing function on: June 03, 2013, 12:50:37 pm
 smiley Not really. Think about it. You hit the pause button at 10 minutes, come back and hit the start button, by the time the video is back in sync and you can play you've only gained an extra second so after the pause you're at 00:10:01. To exploit this you'd then have to press the pause button again before you lost that second, possible but you'd only gain a second for each run through. There are two other ways that you can exploit this that are much more "profitable" and easier.
11  Using Arduino / Project Guidance / Re: Help with timing function on: June 03, 2013, 01:17:17 am
Here's a link to the full code (too big to post directly): http://pastebin.com/27JgCSih
12  Using Arduino / Project Guidance / Help with timing function on: June 02, 2013, 11:36:28 pm
First here is the code:

Code:
void F_countdown() {
  if (ClearLCD == true) {
    lcd.clear();
    ClearLCD = false;
  }
 
  LCDBacklight(0, 0, 255); // Blue
  lcd.setCursor(2, 0);
  lcd.print("Time Started:");
 
  // If second has passed then we subtract that from the AllowedPlaytime
  if (millis() - CurrentMillis > 1000) {
    AllowedPlaytime = AllowedPlaytime - 1000;
    CurrentMillis = millis();
    F_timeDisplay();
   
  // If there is less than 5 minutes of playtime left start sounding an audible alarm at the interval defined. 
  if (AllowedPlaytime <= 300000) { // 5 min
    if (millis() - LastWarningTime > WarningBeepInterval1) {
      F_warning1();
    }
 
  // Or if there is less than 10 seconds of playtime left start sounding an audible alarm at the interval defined.
  else if (AllowedPlaytime <= 10000) { // 10 seconds
    if (millis() - LastWarningTime > WarningBeepInterval2) {
      F_warning2();
    }
  }
}
  }

  if (digitalRead(PauseSW) == LOW) { // Logic is inverted since we're using the internal resistors. When button is pressed the PIN goes LOW, when not pressed it's HIGH.
    lcd.clear();
    state = S_pause;
  }
 
  if (AllowedPlaytime == 0) {
    lcd.clear();
    state = S_timeup;
  }
}

Hopefully that's enoug to get us going, I can post the whole sketch but it's a lot. The part that I'm wondering if anyone can help on is the:

Code:
if (AllowedPlaytime <= 300000) { // 5 min
    if (millis() - LastWarningTime > WarningBeepInterval1) {
      F_warning1();

As you can see when a certain time is reached a warning function is run that sounds an audible alarm (a tone to a speaker). The alarm function is called every x number of seconds/minutes/etc, as defined by WarningBeepInterval1. As set now this sounds a tone every minute (WarningBeepInterval1 = 60000;).

This works great - as the timer counts down and reaches the 5 min mark a tone is sounded every minute 

The issue that I'm having is that if the pause button is pressed if (digitalRead(PauseSW) == LOW) then the program goes into the pause state which causes the main main timer:

Code:
if (millis() - CurrentMillis > 1000) {
    AllowedPlaytime = AllowedPlaytime - 1000;
    CurrentMillis = millis();
    F_timeDisplay();

to stop running. When the start button is pressed then it goes back into the count down function - if you've reached the 5 minute mark and tones have started to sound when the pause button is pressed then when it comes out of pause the tones are out of sync with the main timer. They still sound every minute but, again not in sync with the main timer.

I know this has to do with the fact that I'm using millis() to keep track of the time passed and even in the pause state it's still running so if you pause for 2 minutes and then un-pause if (millis() - LastWarningTime > WarningBeepInterval1) { is true and so it runs like you'd expect it to.

I'm at a loss on how to resolve this and hoping someone can help with ideas. If you need more info, ro the whole sketch, let me know. Thanks.
13  Using Arduino / Project Guidance / Re: Audomatic Garage Door Close on: October 10, 2012, 10:38:09 pm
Ok, changed it so that the calibration runs in setup - this was easy per recommendations I just did:

Code:
for (PIRCalTime = 0; PIRCalTime < 40; PIRCalTime++) {
    Calibrate(); // run the Calibrate function
  }

I also cleaned up the redundant if == true statements as suggested.

I know I got off to a rough start but thanks for all of you for your help. I've learned a lot. Appreciate your time.
14  Using Arduino / Project Guidance / Re: Audomatic Garage Door Close on: October 10, 2012, 03:43:01 pm
Shouldn't the Calibrate function be called from setup rather than loop? Clearly either will work, but why bother checking for it in loop when it's a startup activity only?

I was thinking that, but it has to be called 40 times. A 'for' loop might look better though, called from setup.

Would it cause issues running through it 40 times in setup?
15  Using Arduino / Project Guidance / Re: Audomatic Garage Door Close on: October 10, 2012, 03:28:11 pm
Does it work?

In general in cases like this:

Code:
if (DoorCloseWarn == true) {
    Warn(); // go to the Warn function

Booleans can only be true or false, so testing for "== true" is a bit redundant. How about:


Code:
if (DoorCloseWarn) {
    Warn(); // go to the Warn function

It does work... both my uncle (who I wrote it for) have tested it and it all seems to function correctly. Good point on the DoorCloseWarn == true.

Thanks,
 Adam

True. Honestly, I hadn't considered moving it outside the loop because I was not aware of how to work things outside of the loop. I'll have to play with your suggestion - I guess the benefit is that it's one less thing that has to be checked in the loop.
Pages: [1] 2 3