Pages: [1] 2   Go Down
Author Topic: pulseIn question  (Read 2884 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 26
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm trying to use the pulseIn function to decode a WWV timecode, and I can't seem to get numbers that make sense. I have a separate microcontroller (8051) sending my Arduino a 1Hz signal to simulate constant 1s just to troubleshoot the program, and it's acting extremely oddly.

After a while of completely missitng the mark on pulse timing, after every pulseIn I put a Serial.Print(variable); just to see what it was putting out, and it was always what seemed like a completely random number. In under seconds the pulseIn function was putting out anywhere from 0 to 17,000 into the variables.

The thing that boggles my mind is, the time that it was timing wouldn't even BE 17 seconds, and not once did I send it a pulse that long.

Am I missing something?

Thanks.

Edit: On a side note I did have a post of this nature a week ago but I lost it and just recently figure out how to look at my previous posts. I apologize for a repost, but this issue is at least different, as the code contained in that post did work as expected (aside from pulseIn).
« Last Edit: March 03, 2011, 02:49:14 am by Twombly » Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 217
Posts: 13705
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

COuld you post the code or the URL for the other discussion thread.
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 127
Posts: 8517
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Do you have the GNDs of the two processors connected?

______
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

0
Offline Offline
Newbie
*
Karma: 0
Posts: 26
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Here's the finished code of what I've been using. I didn't connect the GNDs of the two, but even just using a button to 5V with a resistor it gets random numbers. It doesn't have the various Serial.Prints I added to try to debug, but I had them at various stages.

I'm sending a series of timed pulses to pin 8 (though I've tried others in case I burnt the pin out or something), and trying to decode the time code from that. However, like I said, they're all coming back astronomical numbers for short times. My understanding was that the processor waited while it was timing the pulse, and gave the pulse time in milliseconds, but that's not what I've seen.

Code:
// 2011/2/20
#include <LiquidCrystal.h>
#include <Time.h> // initialize library
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);  // pins for LCD
int wwvbitarray[41] = {  //  41 bits because first bit is always no signal and the last bunch are useless
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0};
int wwvinput = 8;  // This is making wwvinput pin 8
unsigned long wwvpulselength;  // This is for the initial synchronizing stage
unsigned long wwvdbrlength;  // This is used for detecting logic 1s, 0s, and markers
int currentMonth;
int currentHour;
int currentMinutes;
int currentSeconds;
int currentDay;
int currentYear = 2011;



void setup()
{
  pinMode(wwvinput, INPUT); // Same as above, wwvinput is pin 8 and an input
  lcd.begin(16, 2);  // initializing the LCD for the size I have
  lcd.print("Please wait."); // Showing something while the decoder finds the time
  Serial.begin(9600)
}

void loop()
{
if(timeStatus() != timeSet)
  wwvpulselength = pulseIn(wwvinput, HIGH);  // This is detecting the 0 second, which will be 1000 milliseconds of HIGH
      Serial.print(wwvpulselength); //THis is what I added to see what the function was returning
      Serial.print(" ");
      if (wwvpulselength > 950000) //  pulseIn times out at 1 second by default, so 950 is what I used
     { setbits();}
  }
  
else {lcd.setCursor(0, 0);
      lcd.print(month());
      lcd.print("/");
      lcd.print(day());
      lcd.print("/");
      lcd.print(year()); // prints month and day
      lcd.setCursor(0, 1); // Sets cursor to bottom left to continue writing
      lcd.print(hour());
      lcd.print(":");
      lcd.print(minute());
      lcd.print(":");
      lcd.print(second());
}
}

void setbits()  //  This is the decoding function to find the logic states for each bit
{
  for (int i=0; i <= 40; i++){ //  41 bits in the array, so it will write to each one; I might be able to drop a couple and do my decoding then
    wwvdbrlength = pulseIn(wwvinput, HIGH);  // this reads the highs of the dB reduced signal and checks the time against if statements
    Serial.print(wwvdbrlength); //This is what I added to see what the function was returning
    Serial.print(" "); //This is to keep them separated
    if (wwvdbrlength < 300000) // markers are 200ms, so 300 gives some leeway
    { wwvbitarray[i] = 2;}
    else if (300000 < wwvdbrlength && wwvdbrlength < 600000) // 1 is 500ms, so 600
    { wwvbitarray[i] = 1;}
    else if (600000 < wwvdbrlength && wwvdbrlength < 900000) // zero will be 800ms of high signal
    { wwvbitarray[i] = 0;}
    else if ( wwvdbrlength > 900000 ) // If the pulse times out or is greater than it should be, it goes back to finding the sync
    { return; }
  }
 currentMinutes = wwvbitarray[9] * 1 + wwvbitarray[10] * 2 + wwvbitarray[11] * 4 + wwvbitarray[12] * 8 + wwvbitarray[14] * 10 + wwvbitarray[15] * 20 + wwvbitarray[16] * 40;
 currentSeconds = 41;
 currentYear = 2011;
 currentHour = (wwvbitarray[19] * 1) + (wwvbitarray[20] * 2) + (wwvbitarray[21] * 4) + (wwvbitarray[22] * 8) + (wwvbitarray[24] * 10) + (wwvbitarray[25] * 20);
 currentDay = (wwvbitarray[29] * 1) + (wwvbitarray[30] * 2) + (wwvbitarray[31] * 4) + (wwvbitarray[32] * 8) + (wwvbitarray[34] * 10) + (wwvbitarray[35] * 20) + (wwvbitarray[36] * 40) + (wwvbitarray[37] * 80) +(wwvbitarray[39] * 100) + (wwvbitarray[40] * 200);
 if (1 <= currentDay <= 31)
   {currentMonth = 1;
 }
 else if (32 <= currentDay && currentDay <= 59)
   {currentMonth = 2;
    currentDay = currentDay - 31;
  }
 else if (60 <= currentDay && currentDay <= 90)
   {currentMonth = 3;
    currentDay = currentDay - 59;
   }
 else if (91 <= currentDay && currentDay <= 120)
   {currentMonth = 4;
    currentDay = currentDay - 90;
   }
 else if (121 <= currentDay && currentDay <= 151)
   {currentMonth = 5;
   currentDay = currentDay - 120;
   }
 else if (152 <= currentDay && currentDay <= 181)
   {currentMonth = 6;
   currentDay = currentDay - 151;
   }
 else if (182 <= currentDay && currentDay <= 212)
  {currentMonth = 7;
  currentDay = currentDay - 181;
  }
 else if (213 <= currentDay && currentDay <= 243)
  {currentMonth = 8;
  currentDay = currentDay - 212;
  }
 else if (244 <= currentDay && currentDay <= 273)
  {currentMonth = 9;
  currentDay = currentDay - 243;
  }
 else if (274 <= currentDay && currentDay <= 304)
  {currentMonth = 10;
  currentDay = currentDay - 273;
  }
 else if (304 <= currentDay && currentDay <= 334)
  {currentMonth = 11;
  currentDay = currentDay - 304;
  }
 else if (335 <= currentDay && currentDay <= 365)
  {currentMonth = 12;
  currentDay = currentDay - 334;
  }
  
  // The above code is just to decode the date and time from the received signals
 setTime(currentHour, currentMinutes, currentSeconds, currentDay, currentMonth, currentYear);
 // setTime is a function of the time.h, this works ok so far  I think. it's hard to tell without valid bit inputs.
 return;
  }
  
« Last Edit: March 03, 2011, 09:22:40 pm by Twombly » Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 127
Posts: 8517
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
if (32 <= currentDay <= 59)

I'm pretty sure there's no way that will work.

Code:
if (32 <= currentDay && currentDay <= 59)

Quote
I didn't connect the GNDs of the two,
Then it will be random, connect them to get a reliable interface.

Quote
but even just using a button to 5V with a resistor it gets random numbers.
Is the button debounced. How do you get regular intervals?

______
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

0
Offline Offline
Newbie
*
Karma: 0
Posts: 26
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


Code:
if (32 <= currentDay && currentDay <= 59)

Thanks, had no idea that would be an issue.

Quote
I didn't connect the GNDs of the two,
Then it will be random, connect them to get a reliable interface.

Quote
but even just using a button to 5V with a resistor it gets random numbers.
Is the button debounced. How do you get regular intervals?

______
Rob


Well my understanding from the pulseIn function is that it will wait for the pulse (timing out after 1000ms), then when it goes high, it will count until it goes back low, then return the number that it counted. To me this implies that the time that it says has passed has to have passed between the two edges. If I'm wrong there, that could be the root of the issue.

If that's what it does, though, I'm not really concerned about debouncing the button or regular intervals, I'm really concerned about why I'm getting anywhere from 0ms to 17000ms returned from the function, within less than a second.
« Last Edit: March 03, 2011, 07:51:12 pm by Twombly » Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 127
Posts: 8517
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You're right about how pulseIn() works.

Quote
I'm really concerned about why I'm getting anywhere from 0ms to 17000ms returned from the function, within less than a second.
From the button or the other processor?

______
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

0
Offline Offline
Newbie
*
Karma: 0
Posts: 26
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You're right about how pulseIn() works.

Quote
I'm really concerned about why I'm getting anywhere from 0ms to 17000ms returned from the function, within less than a second.
From the button or the other processor?

______
Rob

Sorry I didn't clarify that. I added Serial.print(wwvpulselength) and Serial.print(wwvdbrlength), to the code after each pulseIn as well as Serial.being(9600) to try to figure out what was going on. I'll add that to the above code. I even did the pulseIn example program on the pulseIn page (http://www.arduino.cc/en/Reference/PulseIn) hoping maybe it was something in my code, but no matter what the numbers it returned were nonsense. It would return 12000ms, 13000ms, etc. and it would return them within milliseconds of eachother, rather than the 12 seconds the returns imply.

Also, in specific answer to your question, both do the same thing.
« Last Edit: March 03, 2011, 08:07:59 pm by Twombly » Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 127
Posts: 8517
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I can't explain the above but there's no point even looking until we know there's a reliable and stable pulse input.

What are you using now for the pulse input?

______
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

0
Offline Offline
Newbie
*
Karma: 0
Posts: 26
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I connected the grounds together on the two microcontrollers and I'm still getting wildly varying numbers. They seem to stay relatively close (they don't normally jump more than 1000ms at a time), but they're still much much higher than the time it takes to return the value (over 10k milliseconds and the values are returned in less than a second).

The pulses are approximately 500ms. My understanding is that I should get a bunch of (approximately) 500 returns from the function. I could understand 300-800, if it was consistent in that ballpark I would work around it. The numbers I'm getting though are complete nonsense and I don't know why.

The part of the loop:
Code:
wwvpulselength = pulseIn(wwvinput, HIGH);
if (wwvpulselength > 950)
{ setbits();}

immediately goes to the function because any input whatsoever spikes the value of the pulseIn function to 8000ms at the least.

Also, thanks a lot for the help so far, I really appreciate it, for what it's worth.
« Last Edit: March 03, 2011, 08:32:43 pm by Twombly » Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 127
Posts: 8517
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I'd write a short test program, get rid of everything and just have

loop () {
  Serial.print (pulseIn(8, HIGH));
}
______
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 208
Posts: 8853
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Look at the manual for "pulsein()".  It returns MICROseconds, not MILLIseconds.

17000 microseconds is 17 milliseconds is 0.017 seconds.
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

0
Offline Offline
Newbie
*
Karma: 0
Posts: 26
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Look at the manual for "pulsein()".  It returns MICROseconds, not MILLIseconds.

17000 microseconds is 17 milliseconds is 0.017 seconds.

I don't know how I missed that. I'm going to check again with a 555, I think my 8051 is acting up. Thanks a lot for alleviating a huge headache, though. I'm really sorry to waste your time on something so simple Graynomad.
Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 127
Posts: 8517
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

He he, gotcha (and me) smiley

Doesn't explain the variations though, see how is goes when you have a reliable pulse train.
______
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

0
Offline Offline
Newbie
*
Karma: 0
Posts: 26
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well, stripped down the program to just be pulseIn and serial prints and sent it pulses with a 555, and while it wasn't perfect, I think the variation was because I was pressing it during the pulse count, so it was catching the end of the pulses. When it caught the entire pulse, it seemed to be correct.

Thanks a lot guys, I changed my code to reflect the changes.
Logged

Pages: [1] 2   Go Up
Jump to: