/* * 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; } } } }