This is a follow up from another topic, yet is a specific issue.
I'm running this code at the moment
const int frqPin = 5; //Input Pin
const int oneSecond = 1000; //Meassured time
int frqPinState = LOW;
int frq = 0;
int prevFrqPinState = LOW;
unsigned long timer = 0;
void setup()
{
Serial.begin(9600);
pinMode(frqPin, INPUT); //Declared Pin 5 as Input
}
void loop()
{
frqPinState = digitalRead(frqPin); //Reads State of Input Pin
if (frqPinState == LOW) //Creates a previos state
{
prevFrqPinState = LOW;
}
if (frqPinState == HIGH && prevFrqPinState == LOW) //Pulses Counter
{
prevFrqPinState = frqPinState;
frq++;
}
if (millis() - timer > oneSecond) //Time Counter
{
timer = millis(); //Resets Time
Serial.println(frq); //Prints Frequency
frq = 0; //Resets Frequency
}
}
I'm feeding a 5.6K TTL Pulse to (T1)PD5 on AtMega368U
The purpose of this is to count how many pulses I get every second, then I want to feed this count to a serial port.
My issue lies on the fact that the count alters by a specific amount constantly, as if the Arduino is not reading some pulses every so often.
This is what I get now...
5665
5665
5665
5659
5665
5659
5666
5659
5665
5659
5665
5659
5665
5660
5665
5666
5659
5665
5659
5665
5659
5665
5660
5665
5660
If I understand correctly, the moment the Arduino uses the serial pins it might not be reading my pulses...any ideas?
Your input pulses are too fast for that method. What is happening is that you are missing pulses by two mechinisims:-
- In the arduino going off to service regular interrupts, like up dating the millis() counter.
- Each step takes a finite time to execute, therefore timing each high and low is at least plus or minus one one count. That gives a possible spread of 4 counts per pulse.
At that speed you need to use interrupts and an hardware counter / timer.
digitalRead takes more than 100 microseconds to run once. You can use direct port manipulation to speed it up.
I have tried a new approach, following RIDDICK's example using PulseIn:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1272558914/30
Here he uses a average of a specific amount of pulses over time in microseconds. I have come up with this code:
const uint8_t pin = 5; // digital pin #5
const uint32_t oneSecond = 1000;
uint32_t timer = 0;
void setup() {
Serial.begin(9600);
pinMode(pin,INPUT);
digitalWrite(pin,HIGH); // pullup
}
void loop() {
uint32_t sts = micros(); // start time stamp
const uint32_t c = 3000; // wait for 1000 pulses
for (uint32_t i=c; i>0; i--)
pulseIn(pin,HIGH);
uint32_t ets = micros(); // end time stamp
if (millis() - timer > oneSecond)
{
Serial.println((c*1e6/(ets-sts))); // output Hz
timer = millis();
}
}
And now my outputs look like this:
5680.66
5680.66
5680.66
5680.66
5680.66
5680.66
5680.66
5680.66
5680.61
5680.61
5680.61
5680.61
5680.61
5680.61
5680.66
5680.66
5680.66
5680.66
5680.66
5680.66
5680.66
5680.66
5680.66
5680.66
5680.66
5680.66
5680.66
5680.66
5680.66
5680.66
5680.66
5680.66
5680.66
5680.66
5680.66
This is very good!
Thank you for the tips!
Now, I need to learn how to use a Cmos/Static Ram to store a calibration value. I have a older one here, a HM6264LP-70 I like to use, I will open a new Thread to get some help doing such a thing.
You can use the built in EPROM in the Arduino for that.
You mean, I can access the Static Ram for my own use? How do I go about this?