Sensore velocità vento su arduino uno

Buonasera,
ho questo problema: il sensore di velocità del vento funziona solo se lo collego al pin 2 di arduino UNO, ma purtroppo questo pin è già occupato dalla SIM900.
non è un problema di dichiarazione pin nello sketch. il sensore di direzione che è sul pin analogico funziona.
come posso risolvere?? help

Purtroppo NON abbiamo la palla di vetro :grin: e quindi ... senza vedere il codice difficilmente possiamo darti risposte ...

... tirando ad indovinare posso dire che magari quel sensore è letto via interrupt ?

Guglielmo

Secondo me ci hai preso! :grin:

si, ci hai preso :slight_smile:

#include "TimerOne.h"
#include <math.h>

#define WindSensorPin (13)
#define WindVanePin (A3)
#define VaneOffset 0;

int VaneValue; 
int Direction; 
int CalDirection; 
int LastValue; 

volatile bool IsSampleRequired; 
volatile unsigned int TimerCount; 
volatile unsigned long Rotations; 
volatile unsigned long ContactBounceTime; 

float WindSpeed; 

void setup() {

LastValue = 0;

IsSampleRequired = false;

TimerCount = 0;
Rotations = 0; 

Serial.begin(9600);

pinMode(WindSensorPin, INPUT);
attachInterrupt(digitalPinToInterrupt(WindSensorPin), isr_rotation, FALLING);

Serial.println("Davis Anemometer Test");
Serial.println("Speed (MPH)\tKnots\tDirection\tStrength");

Timer1.initialize(500000);
Timer1.attachInterrupt(isr_timer);
}

void loop() {

getWindDirection();

if(abs(CalDirection - LastValue) > 5) {
LastValue = CalDirection;
}

if(IsSampleRequired) {
// convert to mp/h using the formula V=P(2.25/T)
// V = P(2.25/2.5) = P * 0.9
WindSpeed = Rotations * 0.9;
Rotations = 0; 

IsSampleRequired = false;

Serial.print(WindSpeed); Serial.print("\t\t");
Serial.print(getKnots(WindSpeed)); Serial.print("\t");
Serial.print(CalDirection);
getHeading(CalDirection); Serial.print("\t\t");
getWindStrength(WindSpeed);
}
}

void isr_timer() {

TimerCount++;

if(TimerCount == 6)
{
IsSampleRequired = true;
TimerCount = 0;
}
}


void isr_rotation() {

if((millis() - ContactBounceTime) > 15 ) { 
Rotations++;
ContactBounceTime = millis();
}
}

// Convert MPH to Knots
float getKnots(float speed) {
return speed * 0.868976;
}

// Get Wind Direction
void getWindDirection() {

VaneValue = analogRead(WindVanePin);
Direction = map(VaneValue, 0, 1023, 0, 359);
CalDirection = Direction + VaneOffset;

if(CalDirection > 360)
CalDirection = CalDirection - 360;

if(CalDirection < 0)
CalDirection = CalDirection + 360;

}

void getHeading(int direction) {

if(direction < 22)
Serial.print(" N");
else if (direction < 67)
Serial.print(" NE");
else if (direction < 112)
Serial.print(" E");
else if (direction < 157)
Serial.print(" SE");
else if (direction < 212)
Serial.print(" S");
else if (direction < 247)
Serial.print(" SW");
else if (direction < 292)
Serial.print(" W");
else if (direction < 337)
Serial.print(" NW");
else
Serial.print(" N");
}

void getWindStrength(float speed) {

if(speed < 2)
Serial.println("Calm");
else if(speed >= 2 && speed < 4)
Serial.println("Light Air");
else if(speed >= 4 && speed < 8)
Serial.println("Light Breeze");
else if(speed >= 8 && speed < 13)
Serial.println("Gentle Breeze");
else if(speed >= 13 && speed < 18)
Serial.println("Moderate Breeze");
else if(speed >= 18 && speed < 25)
Serial.println("Fresh Breeze");
else if(speed >= 25 && speed < 31)
Serial.println("Strong Breeze");
else if(speed >= 31 && speed < 39)
Serial.println("Near Gale");
else
Serial.println("RUN");
}

mi aiutate a capire come modiifcare il codice per utilizzare il pin 13 ?
aiutino dopo aiutino sto imparando tante cose

... semplicemente NON puoi ... su Arduino UNO i pin che gestiscono direttamente un interrupt con attachInterrupt() sono solo DUE ... il pin 2 e 3.

Per utilizzate degli interrupt su gli altri pin, occorre passare ai "pinChangeInterrupt" ed usare una libreria per la loro gestione ... puoi provare a guardare (e studiare) la EnableInterrupt , installabile sempre dal "library manager" del IDE, che gestisce questo tipo di interrupt, ma non so se essi fanno al tuo scopo (credo abbiano una latenza decisamente superiore).

Guglielmo

Grazie della dritta, andrò a studiarmi ciò che mi hai indicato.
Ho però risolto così che mi fornisce la media valori:

  if (digitalRead(13) == HIGH && oldReed == LOW) {
    oldReed = HIGH;
    clicks++;
  
  }
  else if (digitalRead(13) == LOW)
  {
    oldReed = LOW;
     }

  potDir = analogRead(potPin); 
  potDir = map(potDir, 0, 1023, 0, 500);
  
  for ( int y = 0; y < 2 ; y++ ) {
    if (potDir < (32 + 2)) {
      angle = 113;
      break;
    }
    if (potDir < (41 + 2)) {
      angle = 68;
      break;
    }
    if (potDir < (45 + 2)) {
      angle = 90;
      break;
    }
    if (potDir < (62 + 2)) {
      angle = 158;
      break;
    }
    if (potDir < (90 + 2)) {
      angle = 135;
      break;
    }
    if (potDir < (119 + 2)) {
      angle = 203;
      break;
    }
    if (potDir < (140 + 2)) {
      angle = 180;
      break;
    }
    if (potDir < (198 + 2)) {
      angle = 23;
      break;
    }
    if (potDir < (225 + 2)) {
      angle = 45;
      break;
    }
    if (potDir < (293 + 2)) {
      angle = 248;
      break;
    }
    if (potDir < (308 + 2)) {
      angle = 225;
      break;
    }
    if (potDir < (343 + 2)) {
      angle = 338;
      break;
    }
    if (potDir < (384 + 2)) {
      angle = 0;
      break;
    }
    if (potDir < (404 + 2)) {
      angle = 293;
      break;
    }
    if (potDir < (433 + 2)) {
      angle = 315;
      break;
    }
    if (potDir < (462 + 2)) {
      angle = 270;
      break;
    }
  }
       Serial.println(count);
    if (count < 5)
    {
      valoriMediaClicks[count] = clicks;
      valoriMediaPotDir[count] = potDir;
      Serial.print("valoriMediaPotDir ");
      Serial.println(valoriMediaPotDir[count]);
    }

    if (count >= 5)
    {
      for (int t = 0; t < 4; t++)
      {
        valoriMediaClicks[t] = valoriMediaClicks[t + 1];
        valoriMediaPotDir[t] = valoriMediaPotDir[t + 1];
        Serial.print("valoriMediaPotDir ");
        Serial.println(valoriMediaPotDir[t]);
      }
      valoriMediaClicks[4] = clicks;
      valoriMediaPotDir[4] = potDir;
    }

    for (int t = 0; t < 5; t++)
    {
      clicksMedia += valoriMediaClicks[t];
      potDirMedia += valoriMediaPotDir[t];
    }
    
    if (count >= 5)
    {
      clicksMedia /= 5;
      potDirMedia /= 5;
    }
    else
      clicksMedia /= count + 1;
    potDirMedia /= count + 1;
    
    clicksMedia *= 2.4;
    velocitaDelVento = clicksMedia;

    clicks = 0;  

    if (count < 10)
    {
      valoriMediaVelocita[count] = velocitaDelVento;
      valoriMediaDir[count] = potDirMedia;
    }

    if (count >= 10)
    {
      for (int t = 0; t < count - 1; t++)
      {
        valoriMediaVelocita[t] = valoriMediaVelocita[t + 1];
        valoriMediaDir[t] = valoriMediaDir[t + 1];
      }
      valoriMediaVelocita[count - 1] = velocitaDelVento;
      valoriMediaDir[count - 1] = potDirMedia;
    }

    for (int t = 0; t < 10; t++)
    {
      velocitaMedia += valoriMediaVelocita[t];
      dirMedia += valoriMediaDir[t];
    }

    if (count >= 10)
    {
      velocitaMedia /= 10;
      dirMedia /= 10;
    }
    else
      velocitaMedia /= count + 1;
    dirMedia /= count + 1;
    velocitaMediaVoce = velocitaMedia;
    direzioneMediaVoce = dirMedia;
    Serial.print("velocitaMedia ");
    Serial.println(velocitaMedia);
    clicksMedia = 0;
    potDirMedia = 0;
    velocitaMedia = 0;
    dirMedia = 0;

    count++;
    if (count >= 10) count = 10;

    }

Io ho trovato molto utili:

  1. Pin Change Interrupts – Arxterra
  2. Bare Metal Micro

Sono stati sufficienti per usare i pin change interrupts.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.