Counting pulse in

I will try and explain this the best way I can think off, I'm working on a project where I have to pro-mini's.
The first one uses this code below where it generates some pulses, 2 short pulses (about 250ms arpart) and one about 750ms long, The first one is only for testing the other pro-mini as the unit this will be connected to is the unit that generates the pulses. The idea is that the 2 short pulses will turn a relay on then when the longer pulse is detected it turns the relay off. The testing pro-mini generates the pulses ok, the part I'm not sure about is how to detect how long the 2 short pulses are compared to the longer pulse is.
The pulse code.

//Send out 2 short pulse's to swtich on and longer singal pulse to trun off
const int ledPin =  7;      // Turn on Signal
int ledState = LOW;             // ledState used to set the LED
int Alarm_on = 8;  //Alram on switch signal
int Alarm_off = 9; //Alram off switch signal
unsigned long previousMillis = 0;        // will store last time LED was updated
unsigned long currentMillis ;
const long interval = 250;           // interval at which to blink (milliseconds)
int time_flag = 0; //Timer flag
unsigned long ActivateTime;
long  AlramTime = 750UL; //sound alram for 10 seconds

void setup()
{
  digitalWrite(Alarm_on, HIGH);
  pinMode(Alarm_on, INPUT);
  digitalWrite(Alarm_off, HIGH);
  pinMode(Alarm_off, INPUT);
  pinMode(ledPin, OUTPUT);
  delay(100);
}

void loop() {
  // Checks alram on swtich then goto alrarm on function to send out 2 short pulses (tell other unit to turn on same input pin)
  if (digitalRead(Alarm_on) == LOW) { // check alram on swtich
    time_flag = 1;  //set the down falg to 1
    ActivateTime = millis();
    Turn_on();
  }
  // Checks alram of swtich then goto alrarm of function to send out 1 longer pulses (tell other unit to turn off same input pin)
  if (digitalRead(Alarm_off) == LOW) {
    time_flag = 1;  //set the down falg to 1
    ActivateTime = millis();
    Turn_off();
  }
}
void Turn_on() { // trun on function
  while (time_flag)  {
    unsigned long Tunonmills = millis();
    if (Tunonmills - previousMillis >= interval) {
      // save the last time you blinked the LED
      previousMillis = Tunonmills;

      // if the LED is off turn it on and vice-versa:
      if (ledState == LOW) {
        ledState = HIGH;
      } else {
        ledState = LOW;
      }

      // set the LED with the ledState of the variable:
      digitalWrite(ledPin, ledState);
    }
    if ((time_flag == 1) && (millis() - ActivateTime >= AlramTime)) {
      if (time_flag == 1)
        delay(50);
      time_flag =  0;
      ledState = LOW;
      digitalWrite(ledPin, ledState);
      return;
    }
  }
}
void Turn_off() { //turn off function
  while (time_flag)  {
    unsigned long Tunoffmills = millis();
    if (Tunoffmills - previousMillis >= interval) {
      // save the last time you blinked the LED
      previousMillis = Tunoffmills;
      ledState = HIGH;
      digitalWrite(ledPin, ledState);
    }
    if ((time_flag == 1) && (millis() - ActivateTime >= AlramTime)) {
      if (time_flag == 1)
        delay(50);
      time_flag =  0;
      ledState = LOW;
      digitalWrite(ledPin, ledState);

      return;
    }
  }
}

I've looked at the puslein and been playing around with I seem to capture the first pulse of the 2 short ones which the first one is reading 12397 on the LCD not sure about the second pulse and the longer pulse is showing 39636 on the LCD. the pulse code below

// Include libraries
#include <LiquidCrystal_I2C.h> // I2C LCD display
#include  <Wire.h>
int pin = 7;
unsigned long duration;
unsigned long previousMillis = 0;        // will store last time LED was updated

LiquidCrystal_I2C lcd(0x027, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address
// constants won't change :
const long interval = 1000;           // interval at which to blink (milliseconds)

void setup()
{
  lcd.begin (16, 2); // for 20 X 4  LCD module
  lcd.setBacklightPin(3, POSITIVE); //set back light pin
  lcd.setBacklight(HIGH); //Turn the back light on the LCD
  Serial.begin(9600);
  pinMode(pin, INPUT);
  ///LCD DISPLAY for debugging only removed one sorted
  lcd.setCursor(0, 0);
  lcd.print("====================");
  lcd.setCursor(0, 1);
  lcd.print("pulse test");
  delay(1000);
  lcd.clear();
}

void loop()
{
  duration = pulseIn(pin, HIGH);
  // unsigned long currentMillis = millis();

  //if (currentMillis - previousMillis >= interval) {
  // save the last time you blinked the LED
  //  previousMillis = currentMillis;
  lcd.setCursor(0, 0);
  lcd.print("duration = ");
  lcd.print(duration);
  lcd.print("       ");

  // }

}

This is only the testing for recording the pulse as I'm not 100% sure how long they actually are yet until I can capture the 2 short pulses and the longer pulse, hopefully I should be able to work how to switch the relay on/off afterwards but just need to capture the true pulse.
Is there a better method or correct method to capture the pulse's ?

Why are you not sure about the second pulse? What is the program doing or not doing that you would like to change?

for this I'd use an interrupt...

I didn't code it in but for transient pulses there needs to be some more logic, but this gives you a framework:

volatile uint32_t startMicros, endMicros;
bool gotPulse;

int shortPulseCount, longPulseCount;

const byte pulsePin = 2;

void setup() 
{
  pinMode(pulsePin, INPUT);  // you should have a PullDown resistor
  attachInterrupt(0, interruptTimer, CHANGE);
}

void loop() 
{
  if(gotPulse)
  {
    if (endMicros - startMicros < 300)  // you need to set this
    {
      shortPulseCount++;
    }
    else 
    {
      longPulseCount++;
    }
    gotPulse = false;
  }
  if(shortPulseCount > 1)
  {
    // do something
    shortPulseCount = 0;
  }
  else if (longPulseCount > 0)
  {
    // do something
    longPulseCount = 0;
  }
}

void interruptTimer()
{
  if(digitalRead(pulsePin))
  {
    startMicros = micros;
    return;
  }
  endMicros = micros();
  gotPulse = true;
}

How do you know that the transmitting Arduino is outputting the pulses that you expect? Have you an oscilloscope or logic analyzer? What should the output of pin 7 be if no buttons are pushed?

aarg,
It displays another number more or less straight after, This is only some test code just to measure the pulse I don't think it's the correct way for the long pulse it gives the same number.

BulldogLowell:
for this I'd use an interrupt...

I didn't code it in but for transient pulses there needs to be some more logic, but this gives you a framework:

volatile uint32_t startMicros, endMicros;

bool gotPulse;

int shortPulseCount, longPulseCount;

const byte pulsePin = 2;

void setup()
{
  pinMode(pulsePin, INPUT);  // you should have a PullDown resistor
  attachInterrupt(0, interruptTimer, CHANGE);
}

void loop()
{
  if(gotPulse)
  {
    if (endMicros - startMicros < 300)  // you need to set this
    {
      shortPulseCount++;
    }
    else
    {
      longPulseCount++;
    }
    gotPulse = false;
  }
  if(shortPulseCount > 1)
  {
    // do something
    shortPulseCount = 0;
  }
  else if (longPulseCount > 0)
  {
    // do something
    longPulseCount = 0;
  }
}

void interruptTimer()
{
  if(digitalRead(pulsePin))
  {
    startMicros = micros;
    return;
  }
  endMicros = micros();
  gotPulse = true;
}

Thanks for the code I've tried to compile it but get this error,

C:\Users\Steve\Documents\Arduino\puslin\puslin.ino: In function 'void interruptTimer()':

puslin:66: error: invalid conversion from 'long unsigned int (*)()' to 'uint32_t {aka long unsigned int}' [-fpermissive]



 startMicros = micros;

             ^

groundFungus,
The buttons are held low and once pressed in the test code it jumps to send out the signal to the controller which is high held low with 10K resistor. At the moment I have an LED connected to the pin which I can see it flash, I will try to get the oscilloscope on it a bit later and see what happens

Steveiboy:
Thanks for the code I've tried to compile it but get this error,

should be

startMicros = micros();

dont forget this:

if (endMicros - startMicros < 300)  // you need to set this

You need to make sure that your transmit sketch is doing what you expect before you can try to read the pulses.

groundFungus:
You need to make sure that your transmit sketch is doing what you expect before you can try to read the pulses.

OP's test sketch for transmitting pulses is overly complex... he can simply use blocking functions without any ramifications whatsoever.

Here is an untested version to simply test using Serial Monitor:

const byte pulseOutPin = 4;

void setup() 
{
  Serial.begin(9600);
  pinMode(pulseOutPin, OUTPUT);
}

void loop() 
{
  if(Serial.available())
  {
    char command = Serial.read();
    switch(command)
    {
      case 'L':
        sendLongPulse();
        Serial.println(F("Sent Long Pulse"));
        break;
      case 'S':
        sendShortPulses();
        Serial.println(F("Sent Short Pulses"));
        break;
    }
  }
  delay(1000);
}

bool sendLongPulse()
{
  digitalWrite(pulseOutPin, HIGH);
  delay(500);
  digitalWrite(pulseOutPin, LOW);
  return true;
}

bool sendShortPulses()
{
  digitalWrite(pulseOutPin, HIGH);
  delay(250);
  digitalWrite(pulseOutPin, LOW);
  delay(250);
  digitalWrite(pulseOutPin, HIGH);
  delay(250);
  digitalWrite(pulseOutPin, LOW);
  return true;
}

I have tested both long and short pules on the oscilloscope and can confirm that the short pulses are 248-252ms long x 2 and the long pulses are 748-752ms long.

BulldogLowell thanks for the code I got it working and out putd the data to the screen and it has been a good learning curve, I've found that this just counts the pulse's which is good. I now need to figure out how to make it work, so when it receives the 2 x 250ms short pulses turn a relay on and when it receives a single 750ms turn the relay off which means I need to work out the difference between the 2 of them

I know the set time for the pulses I'm generating and will try and test adjusting the pulse length on both long and short, I'm unable to hook up it to the main part of the unit that gives the set pulses out or to measure the length of them until mid week this is why I thought of generating the pulses to simulate it and get most of the code working on the unit that receives the pulses in. I just use 2 buttons for short and long put the same output pin for the pulse. Hope this kind of makes sense

Steveiboy:
BulldogLowell thanks for the code I got it working and out putd the data to the screen and it has been a good learning curve, I've found that this just counts the pulse's which is good. I now need to figure out how to make it work, so when it receives the 2 x 250ms short pulses turn a relay on and when it receives a single 750ms turn the relay off which means I need to work out the difference between the 2 of them

this may work, turning on and off the onboard LED:

volatile uint32_t startMicros, endMicros;
volatile bool gotPulse;

int shortPulseCount, longPulseCount;

const byte pulsePin = 2;

void setup() 
{
  Serial.begin(9600);
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(pulsePin, INPUT);  // you should have a PullDown resistor
  attachInterrupt(0, interruptTimer, CHANGE);
}

void loop() 
{
  if(gotPulse)
  {
    if (endMicros - startMicros < 300000UL and endMicros - startMicros > 200000UL)  // you need to set this
    {
      shortPulseCount++;
    }
    else if (endMicros - startMicros < 700000UL and endMicros - startMicros > 600000UL)
    {
      longPulseCount++;
    }
    gotPulse = false;
  }
  if(shortPulseCount > 1)
  {
    digitalWrite(LED_BUILTIN, HIGH);
    shortPulseCount = 0;
  }
  else if (longPulseCount > 0)
  {
    digitalWrite(LED_BUILTIN, LOW);
    longPulseCount = 0;
  }
}

void interruptTimer()
{
  if(digitalRead(pulsePin))
  {
    startMicros = micros();
    return;
  }
  endMicros = micros();
  gotPulse = true;
}

Thanks bulldog
I will try the code and study it and see how it goes, I can see your approach how to do it so it should give me a good idea

Steve