[SOLVED] Arduino NANO and interrupt on pin 6?

Pardon me for the most stupid question of this month but I was looking into the code of my weather station, made by a much better programmer than me so I started to doubt my insight...

The Arduino Uno and Nano have only 2 interrupt pins, but in the code below, an interrupt is connected to another digital pin?! To me this is not possible but what happens if this is in the code? It cannot work, true??

The INT0 is used for the anemometer and INT1 is used for the RFM95 LORA module (DIO0)

RAIN_GAUGE_PIN = pin 6 in this case...

  pinMode(RAIN_GAUGE_PIN, INPUT_PULLUP); // Config Pin as Input and turn on the internal Pull Up Resistor
  attachPinChangeInterrupt(RAIN_GAUGE_PIN, rainGaugeClick, FALLING);

basic sketch code:



#include "Config_Options.h"          // User configurable options file
#include <SPI.h>
#include <Wire.h>
#include <RH_RF95.h>
#if (RADIO_MODE == 1)
#include <RH_ASK.h>                // library for RF RX/TX
#endif
#if (SOIL_LEAF_INTERFACE == 1)
#include <WD_OneWire.h>            // Required for Soil / Leaf Interface (Special Version for DS2482s +100)
#include <WD_DallasTemperature.h>  // Required for Soil / Leaf Interface
#endif
#include <Adafruit_ADS1015.h>        // Required for Soil / Leaf Interface
#include <Adafruit_SHT31.h>          // library for SHT31
#include <SHT2x.h>                   // library for SHT2x
#include <HTU21D.h>                  // library for HTU21 Temp/Hum Sensor
#include <VEML6075.h>                // library for VEML6075 UV sensor
#include <Timer.h>
#include <RunningAverage.h>
#include <EEPROM.h>                  // Library to write and read from eeprom      
#define NO_PORTC_PINCHANGES
#define NO_PIN_STATE
#include <PinChangeInt.h>


// -------------------------------------------------------------------------------------
const char* DeviceModel = "4PAT328TX";
const byte  DeviceType  = 0x01;           // TX LoRa Nano - DON'T CHANGE

// --------------------------------------------------------------------------------------
//   Usefull Macros
// --------------------------------------------------------------------------------------
#define setPortHIGH(port, pin) ((port) |= (1 << (pin)))
#define setPortLOW(port, pin) ((port) &= ~(1 << (pin)))
/* ----------------------------------------------------------------*/


// --- Analog Pins ---
#define SOLARRAD_PIN A0
#define INDICEUV_PIN A1
#define BATVOLT_PIN  A6
#define VANE_PIN     A3
#define SYSTEMP_PIN  A7

// --- Digital Pins ---
#define ANEMOMETER_PIN 3
#define VANEPOWER_PIN  4
#define FAN_PIN        5
#define RAIN_GAUGE_PIN 6
#define TX_LED_PIN     7

// OOK 433 Module Pins
#define TX_PIN         8

// RFM Module Pins
#define RFM_CS        10
#define RFM_INTR       2


// --------------------------------------------------------------------------------------
//   Wind Instruments parameters
// --------------------------------------------------------------------------------------
#if (ID2 == 1)

// --- Fine Offset Anemometers ---
#if (WINDSPEED_SENSORTYPE == 10)   // FO anemometer: Speed Pulse/sec 2.98 mph = 1.3334 m/s (4.8 Km/h)
#define ClickPerRev  2           // Default FO anemometer - 2 clicks per revolution
//#define FORM_FACTOR  1.3333
#define FORM_FACTOR  1.26        // A more realistic value! Speed Pulse/sec 2.81 mph = 1.26 m/s (4.54 Km/h)
#endif
#if (WINDSPEED_SENSORTYPE == 11)   // FO anemometer: Speed Pulse/sec 2.98 mph = 1.3334 m/s (4.8 Km/h)
#define ClickPerRev  1           // FO anemometer modified with one Hall Effect Sensor
//#define FORM_FACTOR  1.3333
#define FORM_FACTOR  1.26        // A more realistic value! Speed Pulse/sec 2.81 mph = 1.26 m/s (4.54 Km/h)
#endif

// --- Inspeed Anemometers ---
#if (WINDSPEED_SENSORTYPE == 20)   // Inspeed Vortex Digital 8: Speed Pulse/sec 2.5 mph = 1.1176 m/s
#define ClickPerRev  8
#define FORM_FACTOR  1.1176
#endif
#if (WINDSPEED_SENSORTYPE == 21)   // Inspeed Vortex Hall Sensor : Speed Pulse/sec 2.5 mph = 1.1176 m/s
#define ClickPerRev  1
#define FORM_FACTOR  1.1176
#endif

// --- Davis Anemometers ---
#if (WINDSPEED_SENSORTYPE == 30)   // Davis 6410 anemometer : Speed Pulse/sec 2.25 mph = 1.00584 m/s
#define ClickPerRev  1
#define FORM_FACTOR  1.0058
#endif

// --- Novalynx Anemometers ---
#if (WINDSPEED_SENSORTYPE == 40)   // Novalynx, model 200-WS-02F : Speed Pulse/sec 1.25 mph = 0.5588 m/s
#define ClickPerRev  3
#define FORM_FACTOR  0.5588
#endif

// --- Environmental Measurements Limited ---
#if (WINDSPEED_SENSORTYPE == 50)   // EML, model WSD1 : Speed Pulse/sec 3.34 mph = 1.493 m/s
#define ClickPerRev  1
#define FORM_FACTOR  1.493
#endif

// --- Didcot Instrument Company ---
#if (WINDSPEED_SENSORTYPE == 60)   // DIDCOT, model DWR205 : Speed Pulse/sec 2.2369 mph = 1.000 m/s
#define ClickPerRev  2
#define FORM_FACTOR  1.000
#endif

// --- Vector ---
#if (WINDSPEED_SENSORTYPE == 70)   // Vector Intruments, model A100LK : Speed Pulse/sec 0.514444 m/s
#define ClickPerRev  10
#define FORM_FACTOR  0.5144
#endif
#if (WINDSPEED_SENSORTYPE == 71)   // Vector Intruments, model A100L2 : Speed Pulse/sec 0.514444 m/s
#define ClickPerRev  13
#define FORM_FACTOR  0.5144
#endif
// --- Vector A100R ---
#if (WINDSPEED_SENSORTYPE == 72)   // Vector Intruments, model A100R : Speed Pulse/sec 1.25 m/s
#define ClickPerRev  1
#define FORM_FACTOR  1.25
#endif


// --- Custom type Anemometer ---
#if (WINDSPEED_SENSORTYPE == 99)   // Custom model : Speed Pulse/sec 1.9685 mph = 0.88 m/s
#define ClickPerRev  1
#define FORM_FACTOR  0.880
#endif


// --- Wind --------------------------------------------------------------------
float Wind_Factor = (FORM_FACTOR / ClickPerRev);
volatile unsigned long anem_count = 0;
volatile unsigned long anem_last  = 0;
volatile unsigned long anem_min   = 0xffffffff;
volatile unsigned long thisTime   = 0;

unsigned long twoMinWindAvg = 0, tenMinWindAvg = 0, WindGust = 0;
unsigned long last_WindGust = 50000;

unsigned long last_get_WindAVG_time = 0;

RunningAverage twoMinWindAvg_array(2);
RunningAverage tenMinWindAvg_array(10);


// --- Vane ----------------------------------------------------------------------
#ifdef DEBUG_ID2
const char vaneDirectionsText[16] [4] = {"N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW"};
String WindDir_Text;
#endif
const int vaneValues[] PROGMEM = {66, 84, 92, 127, 184, 244, 287, 406, 461, 600, 631, 702, 786, 827, 889, 946};
const int vaneDirections[] PROGMEM = {1125, 675, 900, 1575, 1350, 2025, 1800, 225, 450, 2475, 2250, 3375, 0, 2925, 3150, 2700};
unsigned int Min_vane_reading = 1024;
unsigned int Max_vane_reading = 0;
unsigned int WindDir = 0;

#endif  // End #if (ID2 == 1)

// --- Rain ----------------------------------------------------------------------
#if (ID3 == 1)
volatile unsigned long rain_count = 0;
volatile unsigned long rain_last = 0;
long RainFall_rate_tips = 0;
long TotalRainTips = 0;
long last_TotalRainTips = 0;
long lasthour_TotalRainTips = 0;
#endif   // End #if (ID3 == 1)


// --------------------------------------------------------------------------------------
//   Other Vars
// --------------------------------------------------------------------------------------
RunningAverage raSolarRad(4);
RunningAverage raIndiceUV(4);
RunningAverage PacketsSentPerHour_array(3);

float IndiceUV = 0;
float TotalRain = 0;      // Used only in Debug Mode
#if (UV_SENSOR == 1)
float UVA = 0, UVB = 0, UVI = 0;
#endif

long TX_Data[5];

int T_ExtS0 = 0, T_ExtS1 = 0;
int H_ExtS0 = 0, H_ExtS1 = 0;
int SL_TempData [4];


unsigned int SL_MoistData [4];
unsigned int OneWire_FamilyID [5];
unsigned int BatVolt = 0, SysTempADC = 0;
unsigned int avg_SolarRad = 0, SolarRad = 0, avg_IndiceUV = 0;
unsigned int PacketsSent_1h = 0;
unsigned int avg_PacketsSentPerHour = 0;

byte PacketID = 0;
byte RSfan = 0;
byte OneWire_numberOfDevices       = 0;
byte OneWire_numberOfTempSensors   = 0;
byte OneWireTsensor_address[4][8];           // Store address of each OneWire Temperature sensor
byte TotalRainTips_Eeprom_adr      = 12;
byte Min_vane_reading_Eeprom_adr   = 20;
byte Max_vane_reading_Eeprom_adr   = 22;


//---------------------------------------------------------
//     Create objects and initialize
//---------------------------------------------------------
#if (SOIL_LEAF_INTERFACE == 1)
WD_OneWire oneWire;
WD_DallasTemperature sensors(&oneWire);
Adafruit_ADS1015 ads;
#endif

#if (TH_SENSOR0 == 0)
Adafruit_SHT31 S0_SHT31 = Adafruit_SHT31();
#endif

#if (TH_SENSOR0 == 1)
SHT21 S0_SHT21;
#endif

#if (TH_SENSOR0 == 2)
HTU21D S0_HTU21;
#endif

#if (TH_SENSOR1 == 0)
Adafruit_SHT31 S1_SHT31 = Adafruit_SHT31();
#endif

#if (TH_SENSOR1 == 1)
SHT21 S1_SHT21;
#endif

#if (UV_SENSOR == 1)
VEML6075 veml6075 = VEML6075();
#endif

// Singleton instance of the radio driver
RH_RF95 rf95(RFM_CS, RFM_INTR);

#if (RADIO_MODE == 1)
RH_ASK ask433(1000, -1, TX_PIN, -1);
#endif

Timer t;

//---------------------------------------------------------
//     Setup Things
//---------------------------------------------------------
void setup()
{
#ifdef DEBUG_ENABLE
  Serial.begin(19200);
#endif

#if (ID2 == 1)
  twoMinWindAvg_array.clear();
  tenMinWindAvg_array.clear();
#endif
  raSolarRad.clear();
  raIndiceUV.clear();
  PacketsSentPerHour_array.clear();

  Wire.begin();
  if (EEPROM.read(10) != 0xAC) FirstRun_SetEeprom();

  //------------------------------------------------------------
  // Setup the RFM95 transmitter
  //------------------------------------------------------------
  if (!rf95.init())
  {
#ifdef DEBUG_ENABLE
    Serial.println(F("RFM95 init failed!"));
#endif
  }
  else
  {
#ifdef DEBUG_ENABLE
    Serial.println(F("RFM95 init done."));
#endif
#if (RADIO_MODE == 0)
    rf95.setFrequency(868.0);
    rf95.setTxPower(14, false);
#else
    rf95.sleep();
#ifdef DEBUG_ENABLE
    Serial.println(F("RFM95 goes to Sleep mode."));
#endif
#endif
  }

  //------------------------------------------------------------
  // Setup the OOK 433 transmitter
  //------------------------------------------------------------
#if (RADIO_MODE == 1)
  ask433.init();
#endif

  //------------------------------------------------------------

  DDRD = DDRD | B10000000;       // pinMode(TX_LED_PIN, OUTPUT); - Pin D7
  DDRB  = DDRB | B100000;        // pinMode(13, OUTPUT); - Led on Pin D13
  setPortLOW(PORTB, 5);          // digitalWrite(13, LOW);
  DDRD = DDRD | B100000;         // pinMode(FAN_PIN, OUTPUT); - Fan Pin D5

#if (SOIL_LEAF_INTERFACE == 1)
  sensors.begin();  // OneWire
  if (oneWire.checkPresence())
  {
    oneWire.deviceReset();
    DeviceAddress currAddress;
    OneWire_numberOfDevices = sensors.getDeviceCount();
#ifdef DEBUG_SOILLEAF
    Serial.println();
    Serial.println(F("DS2482-100 present"));
    Serial.print(F("1Wire Devices : ")); Serial.println(OneWire_numberOfDevices);
#endif
    for (byte i = 0; i < OneWire_numberOfDevices; i++)
    {
      sensors.getAddress(currAddress, i);
      OneWire_FamilyID [i] = currAddress [0];
#ifdef DEBUG_SOILLEAF
      printAddress(currAddress);
#endif
      if (OneWire_FamilyID [i] == 0x28 || OneWire_FamilyID [i] == 0x22)
      {
        for (byte j = 0; j < 8; j++) OneWireTsensor_address[OneWire_numberOfTempSensors][j] = currAddress[j];
        sensors.setResolution(currAddress, 11);
        OneWire_numberOfTempSensors += 1;
      }
    }
  }
#ifdef DEBUG_SOILLEAF
  else  Serial.println(F("DS2482-100 not detected!"));
#endif

  // ads.setGain(GAIN_TWOTHIRDS);  // 2/3x gain +/- 6.144V  1 bit = 3mV      0.1875mV (default)
  ads.begin();
#endif


#if (UV_SENSOR == 1)
  veml6075.begin();
#endif

#if (ID0 == 1)
#if (UnitID == 0)
  t.every(16889, send_SensorID0);
#endif
#if (UnitID == 1)
  t.every(16943, send_SensorID0);
#endif
#if (UnitID == 2)
  t.every(17011, send_SensorID0);
#endif
#if (UnitID == 3)
  t.every(17077, send_SensorID0);
#endif
  //t.every(17000, send_SensorID0);
#endif

#if (ID2 == 1)
  pinMode(ANEMOMETER_PIN, INPUT);
#if (WINDSPEED_SENSORTYPE !=20 || WINDSPEED_SENSORTYPE !=21)
  digitalWrite(ANEMOMETER_PIN, HIGH);                         // Turn on the internal Pull Up Resistor
#endif
  attachInterrupt(digitalPinToInterrupt(ANEMOMETER_PIN), anemometerClick, FALLING);
  interrupts();
#if (WINDDIR_SENSORTYPE < 20)
  pinMode(VANEPOWER_PIN, OUTPUT);
  digitalWrite(VANEPOWER_PIN, LOW);
#endif

  EEPROM.get(Min_vane_reading_Eeprom_adr, Min_vane_reading);
  EEPROM.get(Max_vane_reading_Eeprom_adr, Max_vane_reading);

  /*
      #if (UnitID == 0)
        t.every(2971, read_Wind);
      #endif
      #if (UnitID == 1)
        t.every(3001, read_Wind);
      #endif
      #if (UnitID == 2)
        t.every(3011, read_Wind);
      #endif
      #if (UnitID == 3)
        t.every(3019, read_Wind);
      #endif
  */
  t.every(1000, read_Wind);                                     // Read wind speed (gust) every 3 seconds and Send PacketID2
  t.every(60000, get_WindAVG);                                  // Calls Wind Average function every 60 (Wind_SAMPLE_INTERVAL) seconds
#endif

#if (ID3 == 1)
  pinMode(RAIN_GAUGE_PIN, INPUT_PULLUP); // Config Pin as Input and turn on the internal Pull Up Resistor
  attachPinChangeInterrupt(RAIN_GAUGE_PIN, rainGaugeClick, FALLING);

  EEPROM.get(TotalRainTips_Eeprom_adr, TotalRainTips);

#if (UnitID == 0)
  t.every(30971, send_SensorID3);
#endif
#if (UnitID == 1)
  t.every(31013, send_SensorID3);
#endif
#if (UnitID == 2)
  t.every(31063, send_SensorID3);
#endif
#if (UnitID == 3)
  t.every(31121, send_SensorID3);
#endif
  //t.every(31000, send_SensorID3);

  t.every(3600000UL, TotalRainTips_toEeprom);           // One hour timer to call routine to save Total Rain Tips to eeprom (Routine only save if value is different from last call)
#endif

#if (ID4 == 1)
#if (UnitID == 0)
  t.every(36947, send_SensorID4);
#endif
#if (UnitID == 1)
  t.every(37003, send_SensorID4);
#endif
#if (UnitID == 2)
  t.every(37057, send_SensorID4);
#endif
#if (UnitID == 3)
  t.every(37097, send_SensorID4);
#endif
  //t.every(37000, send_SensorID4);
#endif

#if (ID5 == 1)
#if (UnitID == 0)
  t.every(78989, send_SensorID5);
#endif
#if (UnitID == 1)
  t.every(79031, send_SensorID5);
#endif
#if (UnitID == 2)
  t.every(79103, send_SensorID5);
#endif
#if (UnitID == 3)
  t.every(79159, send_SensorID5);
#endif
  //t.every(79000, send_SensorID5);
#endif

#if (SOIL_LEAF_INTERFACE == 1)
#if ID7 == 1
#if (UnitID == 0)
  t.every(82913, send_SensorID7);
#endif
#if (UnitID == 1)
  t.every(83003, send_SensorID7);
#endif
#if (UnitID == 2)
  t.every(83077, send_SensorID7);
#endif
#if (UnitID == 3)
  t.every(83177, send_SensorID7);
#endif
  //t.every(83000, send_SensorID7);
#endif

#if (ID9 == 1)
#if (UnitID == 0)
  t.every(96931, send_SensorID9);
#endif
#if (UnitID == 1)
  t.every(97001, send_SensorID9);
#endif
#if (UnitID == 2)
  t.every(97073, send_SensorID9);
#endif
#if (UnitID == 3)
  t.every(97127, send_SensorID9);
#endif
  //t.every(97000, send_SensorID9);
#endif
#endif

  t.every(3600000UL, avg_PacketsSentLastHour);  // Every hour
}

// MAIN LOOP
//--------------------------------------------------------------------------------------
void loop()
{
  t.update();

  // Reboot if millis is close to rollover. RTC_Millis won't work properly if millis rolls over.  Takes 49 days to rollover
  //if ( millis() > 4294000000UL ) softReset();
}

// End MAIN LOOP ------------------------------------------------------------------------

Nano isn't enough of a description - it is a form factor that supports multiple processors. I assume you mean a NANO Classic AVR version. The AVR chip has only 2 pins that support full interrupt capability. Most of the other pins support an interrupt when the pin changes state.

Why not?
Arduino Uno/Nano has two external interrupts on pins 2 & 3 - it's true.
But it's true too that the controller has an interrupts of another type - PCINT - available on all GPIOs.

Google "Arduino PCINT interrupts", for example:

1 Like

Thank you very much for the URL!!

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