0

In my recent project, I want square wave which length vary according our timing. And this square wave is take reference as a another square wave.

For that, I made Square wave with help of Arduino.

Here, it's code.

int kPinSqrOut = 13;

void setup() 
{
   pinMode(kPinSqrOut, OUTPUT);
}

void loop()
{
  digitalWrite(kPinSqrOut, HIGH);
  delay(1000);
  digitalWrite(kPinSqrOut, LOW);
  delay(2000);

}

This is just simple HIGH and LOW one pin of arduino and we get Square wave.

Oscilloscope output : Square wave

Now based on this, I'm getting Square wave which length can be able to vary.

Here, it's code.

const uint8_t button_pin = 2;
const uint8_t kPin = 3;

void setup()
{
   pinMode(button_pin, INPUT_PULLUP);
   pinMode(kPin, OUTPUT);
   Serial.begin(9600);
}

void loop()
{
   static int last_button_state = LOW;
   static unsigned int push_count;
   static unsigned long last_press_time;
   int button_state = digitalRead(button_pin);
   unsigned long now = millis();

  // Record when the button is pressed.
  if(last_button_state == LOW && button_state == HIGH)
  {
    push_count++;
    last_press_time = now;

    digitalWrite(kPin, HIGH);
    delay(20);
    digitalWrite(kPin, LOW);
  }

  // Report when the button is released.
  if(last_button_state == HIGH && button_state == LOW)
  {
    unsigned long push_duration = now - last_press_time;
    if (push_duration < 10)   // discard bounce
    {    
        push_count--;
    }
    else
    {
       Serial.print(F("pushes: "));
       Serial.print(push_count);
       Serial.print(F(", duration: "));
       Serial.print(push_duration);
       Serial.println(F(" ms"));
    }
  }

  last_button_state = button_state;
}

And Serial Monitor output :

pushes: 1,    duration: 1001
pushes: 2,    duration: 1000
pushes: 3,    duration: 1001
pushes: 4,    duration: 1002
pushes: 5,    duration: 1001

ve So, basically what I'm try to do. One Arduino generate Square wave and another Arduino take this Square wave as Input and calculate it's length and also generate another Square wave based on first one.

Here, I just detect HIGH state of Square wave and according that generate another Square wave which length vary.

Oscilloscope output :

Square waves

Ideally, all this things work fine. Now, when I apply this things in real implement then not working.

Here, it my square wave(upper one) from 74HC14. But not getting another square wave based on that.

74HC14 Square Wave

So, give me some suggestion.

6
  • The main thing that's different between your two signals is the frequency. An incredibly low frequency signal works. A higher frequency signal doesn't. Maybe that's a clue to your problem? Maybe you should look at frequency counting and duty cycle measurement techniques that don't use digitalRead(). – Majenko Jan 25 '17 at 10:40
  • Oh, and using delay() in generating your output waveform is going to kill the reading of the input waveform completely. – Majenko Jan 25 '17 at 10:41
  • @Majenko Ok, that means I have to replace delay() with something else which work same like delay means provide square wave with desired ms. – Hasan Jan 25 '17 at 11:49
  • Personally I would use either interrupts or Input Capture to measure the incoming duty cycle in the background, and also write a non-blocking square wave output routine using millis() (or micros() if you want faster). – Majenko Jan 25 '17 at 11:50
  • @Majenko Yes, I think that is also one solution. Just using interrupt, detect HIGH state of Square wave and when it detect just write non-blocking square wave output using millis() because I need readings on milliseconds. Thanks for this suggestion, let me try it out. – Hasan Jan 25 '17 at 12:00
1

The only issue in your code is due to the delay in the pin control. You can solve it this way:

void loop()
{
    static int last_button_state = LOW;
    static unsigned int push_count;
    static unsigned long last_press_time;
    static bool kPinPressed = false;
    int button_state = digitalRead(button_pin);
    unsigned long now = millis();

    // Record when the button is pressed.
    if(last_button_state == LOW && button_state == HIGH)
    {
        push_count++;
        last_press_time = now;

        digitalWrite(kPin, HIGH);
        kPinPressed = true;
    }

    if ((kPinPressed) && ((now - last_press_time) >= 20))
    {
        digitalWrite(kPin, LOW);
        kPinPressed = false;
    }

    ...
}

So you turn on the output, then after 20ms you turn it off.

There are just a couple of things not clear for me. What is the last picture? What are the yellow and pink traces? Why is it not behaving correctly? What are the readings on the serial interface?

And most important... What is the time scale? Is it really 10ms/div?

5
  • In last picture, Lower one waveform mean yellow trace is RPM waveform from auto rickshaw. And Upper one mean pink trace is waveform which filter out by RC circuit & passed through 74HC14. So as an output from 74HC14, I got this pink trace mean upper one waveform. – Hasan Jan 25 '17 at 11:55
  • I think may be some noise present on that. That's why. – Hasan Jan 25 '17 at 11:56
  • In serial interface, the reading you see is length of square wave which is generated by arduino. Length is in ms. – Hasan Jan 25 '17 at 11:57
  • 10 ms/ div ? I can't understand what this mean. – Hasan Jan 25 '17 at 12:02
  • @Hasan ok, so there is an RC + 74HC14. Show the actual circuit, and please show also WHAT you expect from as output and what you get – frarugi87 Jan 25 '17 at 15:01
1

Your code. Is designed to work with slow inputs and you are feeding it a much faster input than it can handle.

Solution 1. Use interrupts. Solution 2. Speed up the main loop execution if you insist on polling.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.