Étape 5: Suivez cette desklamp !
OK, alors peut-être il y a une meilleure application de suivi un desklamp...:)
Si vous téléchargez le code que suit à l’Arduino, vous devriez être capable de reproduire les résultats dans la vidéo.
/ * Ce script déplace un actionneur jusqu'à ce que d’entrée analogique maximal est atteint. Alors que c' est exemple d’application est de suivre une source lumineuse avec une cellule solaire qui est attachée à l’extrémité de l’actionneur, il pourrait servir à suivre puisscance quoi que ce soit attaché à la LIGHT_SENSOR_PIN. peut-être comme son source suivi trop ? :) * / #define ACTUATOR_AMP_SENSOR_PIN A5 #define ACTUATOR_PWM_PIN 11 #define ACTUATOR_DIR_PIN 12 #define LIGHT_SENSOR_PIN A4 / / Vitesse maximum est de 255 - c’est la valeur qui est écrit / / à la ACTUATOR_PWM_PIN. Remarque ne pas modifier ou limiter / / détection il n’y aucun travail #define ACTUATOR_SPEED 255 / / la valeur analogique du capteur amp se situe entre elles, c’est / / considérée comme au repos (pas de courant en cours d’élaboration). #define ZEROAMP_RANGE_LOW 505 #define ZEROAMP_RANGE_HIGH 520 / / directions pour l’actionneur (Obtient la valeur ACTUATOR_DIR_PIN) #define rétracter 0 #define EXTEND 1 / / ne bougent pas si échantillonné lumière valeur d’entrée se trouve dans / / STILL_TOLERANCE de g_lastInputValue #define STILL_TOLERANCE 2 / / déplacer le déclencheur jusqu'à ce que la chute de max est inférieur à #define SEEK_TOLERANCE 2 / / nombre minimal de millisecondes de retard entre l’échantillonnage de la ACS712 / / recommandé dans fabricant échantillon source #define SAMPLING_DELAY 1 int g_currentDirection = EXTEND ; int g_lastInputValue = 0 ; limité à 255 char chaînes void serialPrintf (char const * format,...) {tampon char [255] args va_list va_start (args, format); vsprintf (tampon, format, args); va_end(args) ; Serial.println(buffer) ; } booléenne isActuatorMoving() {int val = analogRead(ACTUATOR_AMP_SENSOR_PIN); / / serialPrintf ("lecture de capteur Amp: %d", val); retourner val < ZEROAMP_RANGE_LOW || val > ZEROAMP_RANGE_HIGH;} void stopActuator() {analogWrite (ACTUATOR_PWM_PIN, 0);} boolean almostEqual (int a, int b, int tolérance) {retourner un > = b - tolérance & & un < = b + tolérance;} / / mSeconds = éventuellement se déplacer dans la direction n millisecondes, puis s’arrêtera / / retourne false si mSeconds! = 0 et à fin de voyage boolean moveActuator (int direction int mSeconds = 0) {serialPrintf ("déplacement direction actionneur = %d", direction); analogWrite (ACTUATOR_PWM_PIN, ACTUATOR_SPEED); digitalWrite (ACTUATOR_DIR_PIN, direction); if(mSeconds > 0) {delay(mSeconds) ; boolean stillMoving = isActuatorMoving() ; stopActuator() ; return stillMoving;} retourne true;} / / renvoie le nombre de millisecondes prises unsigned long moveActuatorToEnd (int direction) {long startMs = millis() ; moveActuator(direction) ; tandis que (isActuatorMoving()) {delay(SAMPLING_DELAY); / / léger délai entre le prélèvement le module ACS712 est recommandé} stopActuator() ; stopSP long = millis() ; return stopSP - startMs;} Sub changeDirection (int direction = -1) {si (direction == -1) direction = g_currentDirection + 1 ; masque de bit unique - 0 ou 1, 0 + 1 est 1 et 1 + 1 devient g_currentDirection 0 = direction & 1 ; } / / trouve le maximum d’entrée en passant par la gamme complète du mouvement calibrate() Sub {moveActuatorToEnd(EXTEND); / / démarrer complètement sortie long tMaxInput = 0; / / temps écoulé alors que rétracter cette entrée Max. était atteint int maxInput = 0; / / quel a été le startMs long d’entrée = millis() ; moveActuator(RETRACT) ; tandis que (isActuatorMoving()) {int inputValue = analogRead(LIGHT_SENSOR_PIN) ; if (inputValue > maxInput) {maxInput = inputValue ; tMaxInput = millis() - startMs ; delay(SAMPLING_DELAY);}} stopSP long = millis(); / / revenir au moment quand à max moveActuator (étendre stopSP - startMs - tMaxInput) ; } / / retourne false si à la fin du voyage boolean seekHighInput (int code pin, direction int, int inputValue) {int nextInputValue = inputValue ; int maxInputValue = inputValue stillMoving booléenne booléenne atMax ; serialPrintf ("cherchant à un apport élevé en direction % d. inputValue = %d", direction, inputValue); moveActuator(direction) ; do {delay(SAMPLING_DELAY) ; stillMoving = isActuatorMoving() ; if (nextInputValue > maxInputValue) maxInputValue = nextInputValue ; nextInputValue = analogRead(pin) ; serialPrintf ("stillMoving = %d nextInputValue = %d", stillMoving, nextInputValue); atMax = almostEqual (nextInputValue maxInputValue, SEEK_TOLERANCE) ; } tandis que (stillMoving & & atMax) ; stopActuator() ; Return stillMoving ; } void seekToLight() {boolean stillMovable ; int inputValue = analogRead(LIGHT_SENSOR_PIN) ; int initialValue = inputValue ; if (almostEqual (inputValue, g_lastInputValue, STILL_TOLERANCE)) {return;} stillMovable = seekHighInput (LIGHT_SENSOR_PIN, g_currentDirection, inputValue); inputValue = analogRead(LIGHT_SENSOR_PIN) ; lessThanAtStart booléen = inputValue < initialValue - STILL_TOLERANCE ; si ()! stillMovable || lessThanAtStart) {changeDirection();} / / si nous recevons moins entrée qu’au début de cet appel, changeDirection / / et retour à if max (lessThanAtStart) {seekHighInput (LIGHT_SENSOR_PIN, g_currentDirection, inputValue);} g_lastInputValue = inputValue ; } / / la routine d’installation s’exécute une fois que lorsque vous appuyez sur reset : void setup() {/ / initialiser la communication série 9600 bits par seconde : pinMode (ACTUATOR_PWM_PIN, OUTPUT); pinMode (ACTUATOR_DIR_PIN, OUTPUT); pinMode (entrée, ACTUATOR_AMP_SENSOR_PIN), Serial.begin(9600) ; pinMode (entrée, LIGHT_SENSOR_PIN); / / on n’a vraiment pas besoin de calibrer quoi que ce soit, l’algorithme de recherche devrait traiter / / variance dans les gammes d’entrées pour le capteur de lumière. / / / / source de l’analyse de l’amplitude des mouvements d’entrée plus élevée que calibrate() / / effectue mai venez en pratique dans des environnements de lumière ambiantes élevées, où il est difficile / / pour distinguer une source singulière. L’algorithme de recherche devront être itérée / / sur le meilleur support des environnements de lumière ambiantes élevées / / / / calibrate() ; serialPrintf ("installation complète") ; } / / la routine de la boucle s’exécute maintes et maintes fois pour toujours : void loop() {seekToLight();}