Reading the state of a squere wave pin and Multitasking

Hi, I'm stucked at this problem:
My car is giving a 3% duty circle ~100Hz squere wave with 12V peak whenever the car is unlocked.
I don't know if i said this correctly but basically every ~97ms i read 12V which least ~3ms
I discovered this using a arduino reading the state of the pin and calculating the times, i'm pretty sure i've done it correctly !

When the car is locked, that wire is giving my no more waves at all.

  1. My first attempt was to use some capacitors to smooth the squere wave and make it so long as 100ms, but then the discharge was slow and i coudn't read the car locked status instantly. The capacitor was discharing too slow or too fast, tried multiple values, no improvment, tried multiple discharge resistors -> result -> too slow discharge, OR too fast which means current consumption. :frowning:
    I also posted a topic about finding the right cap and res here but resulting in my attempt #2
    (PS: i used a voltage divider)

  2. Then i removed the capacitor (peak detector circuit) and use the RAW squere wave, I implemented a code that read the time between the waves and if the time is <100 that mean the car is unlocked, BUT after testing it, i realise that my project (even without any delays) have a delay, probably because of the LCD in the first place. And this make the time between the car central locking waves dynamic, as long as (1200ms)

  3. Then i used an interrupt pin instead of a normal one and attach a function that calculate the time between the waves.
    But this slowed down my entire project, the debuging serial, the LCD, all the timing, i was so mad of this that i didn't even see if the reading of the pin was correct!
    (see code 1 for this attempt)

  4. Now, i'm thinking of building a pulse extender using a 555 timer, but this means i'll add up to my car consumtion at least 10mA (acording to datasheet) which is Enormous, believe me! I hope i'm wrong with this consumption, correct my !

Code 1

//in the setup
  attachInterrupt(digitalPinToInterrupt(doorlockPin), doorlockPin_change, CHANGE); 


void doorlockPin_change()
{
  if (digitalRead(doorlockPin) == HIGH) {
    doorlock_wave++;
  }

  if (doorlock_wave >= 2) {
    doorlock = true;
    if (doorlock_timer <= 400)
      doorlock = false;
    doorlock_wave = 1;
  }
  if (doorlock_wave <= 1) {
    doorlock_timer = 0;
  }
}

//in the loop
  doorlock_timer++;

I'm missing what the problem is. If you feed the PWM signal to a digital pin and attach an interrupt handler to the RISING state, as soon as the car is unlocked, you'll know, because the handler will be called. That the handler is called over and over shouldn't be a problem since all it will do is set a boolean flag to true.

PaulS:
I'm missing what the problem is. If you feed the PWM signal to a digital pin and attach an interrupt handler to the RISING state, as soon as the car is unlocked, you'll know, because the handler will be called. That the handler is called over and over shouldn't be a problem since all it will do is set a boolean flag to true.

The problem is obvious.. Can't read that pulse.

And this is right, as soon as i unlock the car it will pulse that 2ms 12v wave and trigger the interrupt, but then, in the next 95ms the wave will be at 0v so how do i know if the car is then locked or is it only the pulse.

More precise: :how do i set the flag as false?

prologikus:
The problem is obvious.. Can't read that pulse.

And this is right, as soon as i unlock the car it will pulse that 2ms 12v wave and trigger the interrupt, but then, in the next 95ms the wave will be at 0v so how do i know if the car is then locked or is it only the pulse.

More precise: :how do i set the flag as false?

flag = false;

aarg:

flag = false;

This is not helpful in any case.
Did u even read my topic?

Create a timer variable in your main program. Compare it with millis(). In your ISR, set the variable to millis() on every rising edge. If millis()-variable > 10ms then you haven't seen a pulse for too long. That is a clear indication of a locked state.

And this is right, as soon as i unlock the car it will pulse that 2ms 12v wave and trigger the interrupt, but then, in the next 95ms the wave will be at 0v so how do i know if the car is then locked or is it only the pulse.

How does the car relock itself when it is unlocked. What do you want to do when an interrupt is received that the car is unlocked?

Indeed, I suspect that you (OP) are confusing the means with the end. In my mind, there could only be one reason for using an interrupt, and that would be to avoid missing any pulses.

//in the setup:
attachInterrupt(digitalPinToInterrupt(doorlockPin), doorlockPin_change, RISING);

//in the loop
doorlock_listen();



void doorlockPin_change()
{
  doorlock_timer = millis();
}


void doorlock_listen()
{

  if ((millis() - doorlock_timer) <= 150) {
    if (doorlock != false) {
      doorlock = false;
      DEBUG_PRINT("Doorlock false");
    }
  }
  else {
    if (doorlock != true) {
      doorlock = true;
      DEBUG_PRINT("Doorlock true");
    }
  }
}

Write this code and still it doesn't work, maybe it's a little mistake or maybe other reasons.
Edit: also, when the car is locked, the code stucks! (lol)

Back you what you said(don't really get it):

cattledog:
How does the car relock itself when it is unlocked. What do you want to do when an interrupt is received that the car is unlocked?

The answer is offtopic, still, short answer: the car receives signal from my key evey 500ms, if no signal for 7 sec then lock the car by pulling that wire (with the pulse) to ground for 200ms (to be sure that the pulse reach ground)

aarg:
Indeed, I suspect that you (OP) are confusing the means with the end. In my mind, there could only be one reason for using an interrupt, and that would be to avoid missing any pulses.

Yes, because as i said and tested, not using one will result in a time between the pulses of even 1200ms because of other functions from my skatch (like lcd print, serial print, maths, more)

I thought I provided a solution to this problem in Reply #3 of your other Thread.

...R

Robin2:
I thought I provided a solution to this problem in Reply #3 of your other Thread.

...R

Me too! But when the lcd is on the digitalRead of my pin is delayed so the distance between pulses is larger
This is why i want to use interrupts, as you can see the code from my #8 replay was similar to your but using interrupt, or at least i tried, but seems like it doens't work either and i don't know why, not i'm looking for the reason.

EDIT:

//in the setup
attachInterrupt(digitalPinToInterrupt(doorlockPin), doorlockPin_change, RISING);

void doorlockPin_change()
{
  doorlock_timer = millis();
}

//in the loop
  if (millis() - last_millis_b >= 300) {
    last_millis_b = millis();
    
    DEBUG_PRINT("Last pulse d:");
    DEBUG_PRINT((millis() - doorlock_timer));
  }

Serial OUTPUT: Between 1 and 3 (a lot of 1)

prologikus:
This is why i want to use interrupts,

In my Reply in the other Thread I said "It might be neater to use an interrupt to detect the rising edge of the pulse"

...R

Thanks for your answers, i'm very tired now, i'll continue tomorrow.

So far it seems like i can't do it, And my main problem is whenever the input on a interrupt pin is LOW, the arduino stucks!

prologikus:
So far it seems like i can't do it, And my main problem is whenever the input on a interrupt pin is LOW, the arduino stucks!

You should use either a FALLING or RISING interrupt.

LOW will cause repeated interrupts (perhaps hundreds) while the signal is LOW

...R

Robin2:
You should use either a FALLING or RISING interrupt.

LOW will cause repeated interrupts (perhaps hundreds) while the signal is LOW

...R

Even i use rising or falling
Even i use internal pullup
The setup stops as attaching the unterrupt

OR if the interrupt pin is not LOW when the setup is done, whenever it get low the loop stucks, in any moment!

I'm using arduino mega, and i use multiple pins to check this (interrupt pins)

Post the complete program that uses a FALLING (or RISING - whichever you consider to be the most sensible) interrupt.

"The loop stucks" is not very helpful for diagnostic purposes.

...R

prologikus:
Yes, because as i said and tested, not using one will result in a time between the pulses of even 1200ms because of other functions from my skatch (like lcd print, serial print, maths, more)

This is one of the parts that I don't really get from you. What could you possibly be doing on a car control Arduino that takes such a long time to complete? LCD and Serial take mere milliseconds, if that much. Maths, well hard to think of anything an Arduino can do with it's tiny memory that would take so long. That leaves the "more" part.

You're also complaining that a 555 timer would take 10 mA of current (wonder which version you're looking at - the common NE555 takes about 3 mA, the TS555CN only 100 uA), but you don't have a problem with an Arduino that's working hard (thus taking well over that 10 mA) plus an LCD plus something that's on the Serial. Sounds like easily 200-300 mA there.

Robin2:
Post the complete program that uses a FALLING (or RISING - whichever you consider to be the most sensible) interrupt.

"The loop stucks" is not very helpful for diagnostic purposes.

...R

Seems like as soon as i plug in the ground pin to an interrupt pin the arduino is not working anymore(even if i don't attach the interrupt)
And if i restart it it got stuck at "lcd.begin"
It's very strange because i already have 2 pins connected to interrupt pins
Edit: if i remove lcd begin from the setup, then i can connect any pins to interrupt pins and nothing happends
Edit2: I only connected my lane on INT0 and INT1, pin 20 and 21, but i forget i also have 3 as INT5 , (the rest of (INT2,3,4 was already in use)) so i connected it there and now the arduino doens't stuck anymore, now i have to redo all my tests to see if now the code is working...

Still... Why my INT0 and INT1 stuck my arduino program is the LCD is in use?

I just posted my code here, it's very long however, because it's all my code

wvmarle:
This is one of the parts that I don't really get from you. What could you possibly be doing on a car control Arduino that takes such a long time to complete? LCD and Serial take mere milliseconds, if that much. Maths, well hard to think of anything an Arduino can do with it's tiny memory that would take so long. That leaves the "more" part.

You're also complaining that a 555 timer would take 10 mA of current (wonder which version you're looking at - the common NE555 takes about 3 mA, the TS555CN only 100 uA), but you don't have a problem with an Arduino that's working hard (thus taking well over that 10 mA) plus an LCD plus something that's on the Serial. Sounds like easily 200-300 mA there.

In the end i think i'll buy TS555CN and use it as pulse extender, seems to be a very simple and effective solution!

about the consumption it's simple, the lcd go to sleep, the arduino do this too, and the serial is only for debuging

prologikus:
I just posted my code here, it's very long however, because it's all my code

Where, in all that code, is the ISR that responds to the RISING or FALLING signal? My text editor could not find either word in it.

When you have a programming problem it is much better to work it out in a short program that only deals with that single problem.

...R

Robin2:
Where, in all that code, is the ISR that responds to the RISING or FALLING signal? My text editor could not find either word in it.

When you have a programming problem it is much better to work it out in a short program that only deals with that single problem.

...R

Ok, i solved it by changing the pin from 20 or 21 (arduino mega) to pin 3
Seems like those 2 pins are not working when i use the LCD, i don't know why..

In the end i used this code:

//in the setup
attachInterrupt(digitalPinToInterrupt(doorlockPin), doorlockPin_change, RISING);


//ISR
void doorlockPin_change()
{
  doorlock_temp = true;
}


//in the loop
  if ((millis() - last_millis_b) >= 150) {
    last_millis_b = millis();
    if (doorlock_step == 0) {           //if this is the first step
      doorlock_temp = false;            //drop the bait
      doorlock_step++;                  //set this step as done
    }
    else {                              //if this is the second step
      if (doorlock_temp == false) {     //if the bait wasn't bitted
        if (doorlock != true) {
          doorlock = true;              //this means the car is locked
          DEBUG_PRINT("Doorlock:");
          DEBUG_PRINT(doorlock);
        }
      }
      else {
        if (doorlock != false) {
          doorlock = false;
          DEBUG_PRINT("Doorlock:");
          DEBUG_PRINT(doorlock);
        }
      }
      doorlock_step = 0;
    }
  }

Don't know if this is the best way from all the ways that i tried when i connected it to the "broken" pins but for now is working..

Still, i'm very courios why those 2 pins are not working when i use the LCD :(, i might need them too