My gate opener, help with millis counting times triggered.

Hi guys, I’m super new to arduino and but have had a lot of fun making a system to replace my old gate controller which died.

I’ve just put a magnetic compass sensor in my driveway to measure deflection in degrees caused by a large metal object (a car) so the gate automatically opens, has a delay, and then closes.

The unit is also operated with RF button thingos. Everything is working just fine and dandy, but I worry that if the compass shifts the gate will go into a constant open/close situation and possibly burn out the 240v motor.

What I would like to do is measure if it opens more then 5 times in 30 minutes via pin 6 (The mag sensor) that it writes in a section of code that stops it working.

if (digitalRead(6) == HIGH && digitalRead(gc) == HIGH && digitalRead(go) == LOW)
 { // OPEN WITH AUTO SHUT from mag sensor, SETS AUTO CLOSE HIGH TO AVOID BEING MIXED UP WITH GENERAL STOPPING
 autoclose = HIGH;
 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); 
 Wire.write(1); 
 Wire.endTransmission();
 delay(2000); // DELAY TO ENSURE GATE PASSES LIMITS, ALSO STOPS BOUNCE
 }

is what I’m doing at the moment, it sets autoclose high so then my auto close code can deal with it differently then just when the buttons are pressed. I want to incorporate the same thing in the trigger code like

if (digitalRead(6) == HIGH && digitalRead(gc) == HIGH && digitalRead(go) == LOW) && Notfaulty == LOW)

I want to use a millis timer to set the NotFaulty variable to high if the gate opens 5 time in 30minutes, therefore stopping the loop which may destroy the motor.

Sorry if that’s long winded and ass about face. Full code below.

#include "Wire.h" // for I2C bus
#define I2C_ADDR 0x20
int button2 = 5; // Button 2 on controller
int button = 2; // Button 1 on controller
int gc = 3; // Gate closed
int go = 4; // Gate open
static int autoclose;
void setup()
{
 autoclose = LOW;
 Wire.begin(); // Wake up I2C bus
  // Set I/O bank A to outputs
 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x00);
 Wire.write(0x00); 
 Wire.endTransmission();
}
void loop() {
  if (digitalRead(button2) == HIGH && digitalRead(gc) == HIGH && digitalRead(go) == LOW)
 { // OPEN WITH AUTO SHUT, SETS AUTOCLOSE HIGH TO AVOID BEING MIXED UP WITH GENERAL STOPPING
 autoclose = HIGH;
 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); 
 Wire.write(1); 
 Wire.endTransmission();
 delay(2000); // DELAY TO ENSURE GATE PASSES LIMITS, ALSO STOPS BOUNCE
 }
if (digitalRead(button) == HIGH && digitalRead(gc) == HIGH && digitalRead(go) == LOW)
 { // OPEN CODE
 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); 
 Wire.write(1); 
 Wire.endTransmission();
 delay(2000); // DELAY TO ENSURE GATE PASSES LIMITS, ALSO STOPS BOUNCE
 }
   if (digitalRead(button) == HIGH && digitalRead(gc) == LOW && digitalRead(go) == HIGH)
 { // CLOSE CODE
 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); 
 Wire.write(2); 
 Wire.endTransmission();
 delay(2000); // DELAY TO ENSURE GATE PASSES LIMITS, ALSO STOPS BOUNCE
 }
   if (digitalRead(gc) == HIGH && autoclose == LOW) // STOP WHEN CLOSED LIMIT IS HIT
 { Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12);
 Wire.write(0); 
 Wire.endTransmission();
 delay(2000);
 } 
  if (digitalRead(go) == HIGH && autoclose == LOW) // STOP WHEN OPEN LIMIT IS HIT
 { Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); 
 Wire.write(0); 
 Wire.endTransmission();
 delay(2000);
 }
   if (digitalRead(go) == HIGH && autoclose == HIGH) // STOP WHEN OPEN LIMIT IS HIT WITH DELAY
 { Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); 
 Wire.write(0); 
 Wire.endTransmission();
 delay(300000); // DELAY FOR GATE TO STAY OPEN
 autoclose = LOW;
  Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); 
 Wire.write(2); // START CLOSING AFTER DELAY
 Wire.endTransmission();
 delay(2000);
 }
 // breakkkkkkkkkkkkkkkkkkkkklowkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk mag sensor trigger code below
   if (digitalRead(6) == HIGH && digitalRead(gc) == HIGH && digitalRead(go) == LOW)
 { // OPEN WITH AUTO SHUT from mag sensor, SETS AUTO CLOSE HIGH TO AVOID BEING MIXED UP WITH GENERAL STOPPING
 autoclose = HIGH;
 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); 
 Wire.write(1); 
 Wire.endTransmission();
 delay(2000); // DELAY TO ENSURE GATE PASSES LIMITS, ALSO STOPS BOUNCE
 }
}

and there’s a seperate arduino on the mag controller running pin 13 high if the heading changes

/*
  HMC5883L Triple Axis Digital Compass. Compass Example.
  Read more: http://www.jarzebski.pl/arduino/czujniki-i-sensory/3-osiowy-magnetometr-hmc5883l.html
  GIT: https://github.com/jarzebski/Arduino-HMC5883L
  Web: http://www.jarzebski.pl
  (c) 2014 by Korneliusz Jarzebski
*/

#include <Wire.h>
#include <HMC5883L.h>
HMC5883L compass;

void setup()
{
  Serial.begin(9600);
pinMode(13, OUTPUT);
  // Initialize Initialize HMC5883L
  Serial.println("Initialize HMC5883L");
  while (!compass.begin())
  {
    Serial.println("Could not find a valid HMC5883L sensor, check wiring!");
    delay(500);
  }

  // Set measurement range
  compass.setRange(HMC5883L_RANGE_1_3GA);

  // Set measurement mode
  compass.setMeasurementMode(HMC5883L_CONTINOUS);

  // Set data rate
  compass.setDataRate(HMC5883L_DATARATE_30HZ);

  // Set number of samples averaged
  compass.setSamples(HMC5883L_SAMPLES_8);

  // Set calibration offset. See HMC5883L_calibration.ino
  compass.setOffset(0, 0);
}

void loop()
{
  Vector norm = compass.readNormalize();

  // Calculate heading
  float heading = atan2(norm.YAxis, norm.XAxis);

  // Set declination angle on your location and fix heading
  // You can find your declination on: http://magnetic-declination.com/
  // (+) Positive or (-) for negative
  // For Bytom / Poland declination angle is 4'26E (positive)
  // Formula: (deg + (min / 60.0)) / (180 / M_PI);
  float declinationAngle = (4.0 + (26.0 / 60.0)) / (180 / M_PI);
  heading += declinationAngle;

  // Correct for heading < 0deg and heading > 360deg
  if (heading < 0)
  {
    heading += 2 * PI;
  }

  if (heading > 2 * PI)
  {
    heading -= 2 * PI;
  }

  // Convert to degrees
  float headingDegrees = heading * 180/M_PI; 

  // Output
  Serial.print(" Heading = ");
  Serial.print(heading);
  Serial.print(" Degress = ");
  Serial.print(headingDegrees);
  Serial.println();

  delay(100);
  digitalWrite(13, LOW);
if (headingDegrees  < 10)
{ (digitalWrite(13, LOW));
}else
{
  (digitalWrite(13, HIGH));
}
}

You should have a function that opens the gate, and one that closes it. Replicating the code every time you want to open or close the gate is wrong.

You can know when the sensor says that the gate needs to open. Put that in an array. When a time in the array gets to be more than 30 minutes old, move everything else up. If the array gets to have 6 elements in it, the gate has an issue.

Well, it may not be pretty but it has worked for the past 2 months with no faults, and I dont want to change too much at this stage as it’s wired into 240v relays and the last thing I want is a short.

Am hoping to come up with a millis arrangement for the triggering so it’s safe from failure of the magnetic compass.

Is it possible? Or would I have to rewrite all of the above?

Is it possible?

Yes.

   if (digitalRead(6) == HIGH && digitalRead(gc) == HIGH && digitalRead(go) == LOW && faultdet == LOW)
 { // OPEN WITH AUTO SHUT from mag sensor, SETS AUTO CLOSE HIGH TO AVOID BEING MIXED UP WITH GENERAL STOPPING
 autoclose = HIGH;
 fault = fault + 1;
 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); 
 Wire.write(1); 
 Wire.endTransmission();
 delay(2000); // DELAY TO ENSURE GATE PASSES LIMITS, ALSO STOPS BOUNCE
 }
 if (fault == 5)
 {faultdet = HIGH;
 }
  if (timer0 > interval) {
    timer0 -= interval; //reset the timer
    fault = 0;
  }
  Serial.println(fault);
  Serial.println(faultdet);
}

Thanks for your help, I found the answer myself. :)

jakeoo: Thanks for your help, I found the answer myself. :)

Usually the most satisfying way.

It would be great if some other Forum users followed your example :)

...R

Hi Jakeo,

Your project sounds cool, I’m not sure what country you live in but if it is the UK I thought I should let u know that by using your gate project in real life you will be braking a large list of HSE guidelines, if it’s not perfect and causes an accident you will be in big trouble.

Just a friendly heads up.

Hope it is all going well.