Hi to everyone,
These are my first steps on programming, and age has dropped my learning curve, my English are not enough, so please be patient! ![]()
I decided to extend the abilities of a card reader- logger, supporting 2 doors, to an alarm system.
The problem has 2 parts, this is the first one.
-
When the card reader reads an unknown card, produces approximately 3x 250 sine-wave pulses during 500ms (2,5KHz):
3 short beeps during 500ms, 750 pulses.
This should be converted to WrongID output (to serial, and pin7). -
When a door sensor alarm occurs, outSensorState (5) and/or inSensorState(6), the reader produces constand sinewave 2,5KHz (1250 pulses during 500ms).
This should be converted to outSensorAlarm output (to serial, and pin8) and /or inSensorAlarm output (to serial, and pin9).
All these should happen, only if alarmState (pin 4) is LOW (alarm is active).
Borrowing the code provided by dc42 at : Frequency Counter Library - Science and Measurement - Arduino Forum
and some others, and adding what I understood it should be right, I came up with this code:
// Frequency counter sketch, for measuring frequencies low enough to execute an interrupt for each cycle
// Connect the frequency source to the INT0 pin (digital pin 2 on an Arduino Uno)
volatile unsigned long firstPulseTime;
volatile unsigned long lastPulseTime;
volatile unsigned long numPulses;
const int ledPin = 13;    //If I want to see when and for how long it counts
const int alarmState = 4;   //in LOW equals ALARM ON
const int outSensorState = 5; //in LOW equals OUTDOOR OPENED
const int inSensorState = 6; //in LOW equals INDOOR OPENED
const int WrongID = 7;    //out HIGH ACTIVE
const int outSensorAlarm = 8; //out HIGH ACTIVE
const int inSensorAlarm = 9; //out HIGH ACTIVE
void isr()
{
 unsigned long now = micros();
 if (numPulses == 1)
 {
  firstPulseTime = now;
 }
 else
 {
  lastPulseTime = now;
 }
 ++numPulses;
}
void setup()
{
 Serial.begin(9600);  // this is here so that we can print the result
 pinMode(4, INPUT);  // reads the alarm state, on or off. Should be LOW alarm on maybe pullup res internally
 pinMode(5, INPUT);  // reads the outer sensor alarm , HIGH, door closed.
 pinMode(6, INPUT);  // reads the inner sensor alarm , HIGH, door closed.
 pinMode(7, OUTPUT);  // IF alarm on: if pulses are : 650 < numPulses < 1000 @500ms, then "unknown ID"
 pinMode(8, OUTPUT);  // IF alarm on: if pulses are : numPulses >= 1000 @500ms, and 5=LOW then "out sensor alarm" & 8=HIGH
 pinMode(9, OUTPUT);  // IF alarm on: if pulses are : numPulses >= 1000 @500ms, and 6=LOW then "out sensor alarm" & 9=HIGH
 digitalWrite(7, LOW);
 digitalWrite(8, LOW);
 digitalWrite(9, LOW);
 pinMode(3, OUTPUT);  // put a PWM signal on pin 3, then we can connect pin 3 to pin 2 to test the counter
 analogWrite(3, 128);
}
// Measure the frequency over the specified sample time in milliseconds, returning the frequency in Hz
unsigned int readFrequency(unsigned int sampleTime)
{
 numPulses = 0;           // prime the system to start a new reading
 digitalWrite(ledPin, LOW);
 attachInterrupt(0, isr, RISING);  // enable the interrupt
 delay(sampleTime);
 detachInterrupt(0);
 digitalWrite(ledPin, HIGH);
 return (numPulses < 3) ? 0 : (1000000UL * (numPulses - 2))/(lastPulseTime - firstPulseTime);
}
void loop()
{
 unsigned int freq = readFrequency(500); // put here the sample time
 Serial.println(freq);
 Serial.println(numPulses);
 if ((alarmState == LOW) && (numPulses > 650) && (numPulses < 1000))
  {
   Serial.println("Unknown ID");
   digitalWrite(WrongID, HIGH);
   delay(1000);
  }
 if ((alarmState == LOW) && (numPulses >= 1000) && (outSensorState == LOW))
  {
   Serial.println("OUT SENSOR ALARM");
   digitalWrite(outSensorAlarm, HIGH);
   delay(1000);
  }
 if ((alarmState == LOW) && (numPulses >= 1000) && (inSensorState == LOW))
  {
   Serial.println("IN SENSOR ALARM");
   digitalWrite(inSensorAlarm, HIGH);
   delay(1000);
  }
Â
 delay(1000);
}
1st problem: this thing counts again and again and again. What should I do to make it start counting, when the first or second pulse arrives? Duration should be 500ms.
2nd problem: The only thing I get, is on serial, frequency and pulses. For the test, I use pin 3 output, and change the 650 to 65 and 1000 to 100 numPulses.
Probably, I do something wrong with the ifs'
I tried other combinations:
void loop()
{
 unsigned int freq = readFrequency(500); // put here the sample time
 Serial.println(freq);
 Serial.println(numPulses);
 if (alarmState == LOW)
  {
   if ((numPulses > 65) && (numPulses < 100))
   {
   Serial.println("Unknown ID");
   digitalWrite(WrongID, HIGH);
   delay(1000);
   }
   if (numPulses >= 100)
   {
    if (outSensorState == LOW)
    {
     Serial.println("OUT SENSOR ALARM");
     digitalWrite(outSensorAlarm, HIGH);
     delay(1000);
    }
    if (inSensorState == LOW)
    {
     Serial.println("IN SENSOR ALARM");
     digitalWrite(inSensorAlarm, HIGH);
     delay(1000);
    }
   }
  }
Â
 Â
 delay(1000);
}
nothing better.
For the sine to square conversion, I will try NE555, and I think it will be ok, except if there is a better way.
The second part, takes the 3 outputs, and puts them to a GSM shield, with 4 inputs and 4 outputs, a 2 way communication with SMS. I found with inputs, found with outputs, but not both...
Sorry for the detailed explanation, usually I start from Adam and Eve!
Thanks for your time and your patience !