/*
* This file is part of Detour
* Electronic object that displays arrow patterns
*
* This project is part of Accrochages
* See http://accrochages.drone.ws
*
* (c) 2008 Sofian Audry (info@sofianaudry.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include
#include
#include "arrow_animation_data.h"
/*
* Definitions and constants.
*/
#define PUSHBUTTON_IN 2 // Pin for pushbutton.
#define PHOTO_IN 3 // Pin for the photoresistor (for daylight sleep mode)
#define TIME_STEP 500 // Time between each frame.
#define TIME_BETWEEN_ANIMATIONS 4000 // Time between each animation.
// In MODE_RANDOM, once every TIME_RANDOM_CHANGE_DIRECTION ms, there
// is a 50% probability that direction of the arrow will change.
#define TIME_RANDOM_CHANGE_DIRECTION 300000L
#define N_LEDS N_PIXELS // Number of LEDS.
#define LED_BRIGHTNESS 0.3f // Brightness of the LEDs (for energy saving)
// Internal use (for LEDs brightness).
#define LED_PERIOD_US 1000L
const long LED_PERIOD_US_ON = (long) (LED_PERIOD_US * LED_BRIGHTNESS);
const long LED_PERIOD_US_OFF = (long) (LED_PERIOD_US * (1 - LED_BRIGHTNESS));
// On/off (can be changed wether you opt for pull-up/pull-down LEDs)
#define ON HIGH
#define OFF LOW
// The different modes.
#define MODE_RANDOM 0 // 50% chances of changing direction every TIME_RANDOM_CHANGE_DIRECTION ms
#define MODE_LEFT 1 // Left arrow
#define MODE_RIGHT 2 // Right arrow
// The ordrered N_LEDS pin numbers of the LEDs.
// NOTE: This is useful if you make an error in soldering your circuit and you
// need to reorder your pins (like I did) ;)
//const byte LED_PINS[] = { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 };
const byte LED_PINS[] = { 1, 11, 12, 4, 5, 6, 7, 8, 9, 10 };
/*
* Library.
*/
// Returns true 50% of the time.
boolean randomBoolean() {
return (random(2) == 0);
}
// Clears the LEDs.
void clear() {
for (int pin=0; pin 1000) {
goingLeft = !goingLeft;
count = 0;
}
count++;
};
clear();
// for now don't do this because not volatile ... we'll figure out later
resetAnimation = true;
block = false; // Release mutex.
}
}
/*
* Sleep during daylight methods.
*/
#define SLEEP_TOLERANCE 500 // Number of times we tolerate to read a HIGH value in PHOTO_IN
// before switching to sleep mode.
// Wake up.
void wakeUpNow() // here the interrupt is handled after wakeup
{
resetAnimation = true;
// execute code here after wake-up before returning to the loop() function
// timers and code using timers (serial.print and more...) will not work here.
// we don't really need to execute any special functions here, since we
// just want the thing to wake up
}
// Go to sleep.
void sleepNow() // here we put the arduino to sleep
{
clear();
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
sleep_enable(); // enables the sleep bit in the mcucr register
// so sleep is possible. just a safety pin
attachInterrupt(1, wakeUpNow, LOW); // use interrupt 0 (pin 2) and run function
// wakeUpNow when pin 2 gets LOW
sleep_mode(); // here the device is actually put to sleep!!
// THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP
sleep_disable(); // first thing after waking from sleep:
// disable sleep...
detachInterrupt(1); // disables interrupt 0 on pin 2 so the
// wakeUpNow code will not be executed
// during normal running time.
}
// Returns true iff we evaluate this is daylight.
boolean isDayLight() {
int k = 0;
while (digitalRead(PHOTO_IN) == HIGH) {
k++;
if (k >= SLEEP_TOLERANCE) {
return true;
}
}
return false;
}
/*
* Main methods.
*/
void setup() {
// Set pin modes.
for (int pin=0; pin TIME_RANDOM_CHANGE_DIRECTION)) {
startTime = millis();
clear();
if (randomBoolean())
goingLeft = !goingLeft;
}
}
}
}