Go Down

Topic: pulseIn question (Read 3232 times) previous topic - next topic

Twombly

Mar 03, 2011, 08:47 am Last Edit: Mar 03, 2011, 08:49 am by Twombly Reason: 1
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).

robtillaart

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

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

Graynomad

Do you have the GNDs of the two processors connected?

______
Rob
Rob Gray aka the GRAYnomad www.robgray.com

Twombly

#3
Mar 04, 2011, 12:21 am Last Edit: Mar 04, 2011, 03:22 am by Twombly Reason: 1
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: [Select]
// 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;
 }
 

Graynomad

Code: [Select]
if (32 <= currentDay <= 59)

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

Code: [Select]
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
Rob Gray aka the GRAYnomad www.robgray.com

Twombly

#5
Mar 04, 2011, 01:49 am Last Edit: Mar 04, 2011, 01:51 am by Twombly Reason: 1


Code: [Select]
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.

Graynomad

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
Rob Gray aka the GRAYnomad www.robgray.com

Twombly

#7
Mar 04, 2011, 02:00 am Last Edit: Mar 04, 2011, 02:07 am by Twombly Reason: 1

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.

Graynomad

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
Rob Gray aka the GRAYnomad www.robgray.com

Twombly

#9
Mar 04, 2011, 02:15 am Last Edit: Mar 04, 2011, 02:32 am by Twombly Reason: 1
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: [Select]
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.

Graynomad

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

loop () {
  Serial.print (pulseIn(8, HIGH));
}
______
Rob
Rob Gray aka the GRAYnomad www.robgray.com

johnwasser

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

17000 microseconds is 17 milliseconds is 0.017 seconds.
Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Twombly


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.

Graynomad

He he, gotcha (and me) :)

Doesn't explain the variations though, see how is goes when you have a reliable pulse train.
______
Rob
Rob Gray aka the GRAYnomad www.robgray.com

Twombly

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.

Go Up