2015-12-09 2 views
1

En écrivant un programme Netduino 3 qui contrôlera les lumières de tour et d'autres relais pour les hayrides. Mon programme a été écrit avant d'avoir l'appareil, donc je ne sais pas comment ça va marcher, mais j'ai déjà un problème avec l'un des boutons (hazardButton). Lorsque vous appliquez 3.3v, l'interruption ne se déclenche pas. Appliquer 5v fait la même chose, mais en appliquant GND il déclenche l'interruption, mais en réappliquant GND il ne désactive pas l'interruption.Incohérence Netduino InterruptPort

Voici mon code:

using System; 
using System.Net; 
using System.Net.Sockets; 
using System.Threading; 
using Microsoft.SPOT; 
using Microsoft.SPOT.Hardware; 
using SecretLabs.NETMF.Hardware; 
using SecretLabs.NETMF.Hardware.Netduino; 

namespace Tractor_Mate 
{ 
    public class Program 
    { 
     static InterruptPort hazardButton = new InterruptPort(Pins.GPIO_PIN_D0, false, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth); 

     static OutputPort hazardLights = new OutputPort(Pins.ONBOARD_LED, false); 

     static bool hazardsActive = false; 

     public static void Main() 
     { 
      Debug.Print("Initializing Inputs... "); 

      hazardButton.OnInterrupt += new NativeEventHandler(hazardButton_OnInterrupt); 

      Thread.Sleep(Timeout.Infinite); 
     } 

     static void hazardButton_OnInterrupt(uint data1, uint data2, DateTime time) 
     { 
      while (data2 == 0) 
      { 
       hazardLights.Write(true); 
       Thread.Sleep(500); 
       hazardLights.Write(false); 
       Thread.Sleep(500); 

       hazardsActive = true; 
      } 
      hazardsActive = false; 
     } 
    } 
} 

Im obtenir le problème avec le Hazard Lights et n'a pas essayé tous les autres encore. Im câblage les boutons vers le haut de sorte que lorsque la broche va HIGH il se déclenchera, et puis quand LOW il l'éteint.

+0

Votre message (source) est assez long, plus long que nécessaire pour le débogage. S'il vous plaît voir [mcve] pour plus d'informations. Notez que vous avez dit que vous avez un problème avec un bouton - mais vous ne nous avez pas dit lequel. – KevinDTimm

+0

@KevinDTimm J'ai raccourci la source, et j'espère clarifié ma question plus. – hightekjonathan

+0

On dirait que vous déclenchez sur les deux bords, par exemple, il s'allume lorsque vous appliquez GND, puis s'éteint lorsque vous supprimez GND. Si vous voulez appuyer une fois sur le bouton pour l'allumer et une fois pour l'éteindre, vous devez inverser la logique. De même, vous ne devriez pas avoir de boucles infinies dans les gestionnaires d'événements, vous devez utiliser une minuterie pour effectuer la logique. –

Répondre

0
public class Program 
{ 
    static InterruptPort hazardButton = new InterruptPort(Pins.GPIO_PIN_D0, false, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth); 

    static OutputPort hazardLights = new OutputPort(Pins.ONBOARD_LED, false); 

    static volatile bool hazardsActive = false; 

    public static void Main() 
    { 
     Debug.Print("Initializing Inputs... "); 

     hazardButton.OnInterrupt += new NativeEventHandler(hazardButton_OnInterrupt); 
     bool lightOn = true; 

     while (true) 
     { 
      if (!hazardsActive) 
      { 
       hazardLights.Write(false); 
      } 
      else 
      { 
       hazardLights.Write(lightOn); 
       lightOn = !lightOn; 
      } 
      Thread.Sleep(500); 
     } 
    } 

    static void hazardButton_OnInterrupt(uint data1, uint data2, DateTime time) 
    { 
     hazardsActive = !hazardsActive; 
    } 
} 

Je suis incapable de le tester puisque je n'ai pas le SDK Netduino installé (j'ai un Netduino, mais sa fait un moment que je joue avec lui). Le principe est assez simple:

L'interruption active ou désactive les risques. La variable est marquée volatile car elle peut être définie à partir de plusieurs threads. Elle doit être lue dans le registre et non dans un cache de threads. Par conséquent, volatile indique au compilateur de ne pas l'optimiser.

La méthode main comporte une boucle infinie qui permet d'examiner si les dangers sont activés ou désactivés. Lorsque les dangers sont désactivés (première partie du if), il écrit faux sur la broche de sortie (en éteignant les lumières, sauf si la broche est inversée). Lorsque les dangers sont activés (else partie), il écrit une valeur sur la broche, puis inverse la valeur, la prochaine fois qu'elle l'éteint, puis l'allume puis l'éteint, etc. La dernière partie de la boucle attend juste 500ms avant de boucler à nouveau.

Remarque

En fonction de la « qualité » des contacts du bouton que vous utilisez, vous devrez peut-être ajouter une logique anti-rebond au gestionnaire d'interruption. Le "rebond" est un phénomène avec des contacts de commutation (ou tout autre contact mécanique) qui peuvent provoquer l'ouverture/la fermeture du contact très rapidement lors du changement d'état. Cela est dû au signal électrique qui comble le vide car les contacts sont très proches les uns des autres (pensez à l'électricité statique qui saute un trou). Beaucoup de fois cela est géré sur le côté matériel par un condensateur, mais je ne suis pas sûr pour le Netduino comment il le gère.

+0

Comment est-ce que j'ajusterais pour le «rebondir»? Est-ce que je vérifierais juste si l'interruption est survenue dans un certain temps, et si elle a 'return' et l'ignore? – hightekjonathan

+0

C'est un moyen, voici quelque chose de spécifique à Netduino de [les forums Netduino] (http://forums.netduino.com/index.php?/topic/2431-input-debounce/) pour le debouncing. –