Go Down

### Topic: Delaymicroseconds not accurately working? (Read 651 times)previous topic - next topic

#### donperry

##### May 03, 2018, 01:37 am
The problem I'm having is that when delayMicroseconds is used I get all sort of finicky RPM on the output of this thing. When I use delay (and divide by 1000) it works but it doesn't smoothly transition
because i need the resolution of microseconds, not milliseconds. For example, 9000 RPM has a delay between spark of 0.01333 seconds, or 13.3 ms [1/(9000/60)*2]. delay doesn't accept decimals so only 13 would be recognized.

Is there something I'm overlooking?

Code: [Select]
`int engspeedV=analogRead(A5);engspeedV = map(engspeedV, 0, 1023, 1000, 9000); //sim engine speed with a variable voltage inputdouble period=spark(engspeedV); //converts the engine speed to a time slice per second  analogWrite(sparkPin,1023); //Coilpack activate and dischargesdelay(5); //discharge period of 5msanalogWrite(sparkPin,0); //end discharge perioddouble finalDelay=(period-5)*1000); //the period of wait before the other discharge cycle  fires againdelayMicroseconds(finalDelay); //try to apply the delay here`

#### larryd

#1
##### May 03, 2018, 01:50 am
We need to see the whole sketch to see what might be affecting things.

https://www.arduino.cc/reference/en/language/functions/time/delaymicroseconds/
delayMicroseconds(finalDelay);   try 'unsigned int' for finalDelay
"the largest value that will produce an accurate delay is 16383"

BTW delayMicroseconds has a granularity if 4us.

No technical PMs.
If you need clarification, ask for help.

#### donperry

#2
##### May 03, 2018, 03:55 amLast Edit: May 03, 2018, 03:56 am by donperry
Code: [Select]
`int sparkPin=7;void setup() {  // put your setup code here, to run once:pinMode(sparkPin,OUTPUT);pinMode(13,INPUT);pinMode(A5,INPUT);Serial.begin(57600);}void loop() { int engspeedV=analogRead(A5);engspeedV = map(engspeedV, 0, 1023, 1000, 9000);   double period=spark(engspeedV);    analogWrite(sparkPin,1023);delay(5);analogWrite(sparkPin,0);double finalDelay=round((period-5)*1000);//delayMicroseconds(finalDelay); //counting up rpmSerial.println(finalDelay); }double spark(double rpm){double hz = (1.0/60)*rpm/2;double slice_duration = 1.0/hz;return slice_duration*1000;}`

#### arduino_new

#3
##### May 03, 2018, 06:02 am
Delaymicroseconds() does not take a double as an argument but an unsigned long

#### westfw

#4
##### May 03, 2018, 06:13 am

Quote
Delaymicroseconds() does not take a double as an argument but an unsigned long
Yeah, but it should convert automatically for you...

You may be running into the fact that floating point calculations (and also analogRead) take quite a long time compared to microseconds - 150+ cycles for simple operations,  ~500 cycles for divide, up to 3000 cycles for some of the math functions...
https://www.nongnu.org/avr-libc/user-manual/benchmarks.html

#### donperry

#5
##### May 03, 2018, 06:31 am
HOLY SMOKES

I changed analogWrite  to digitalWrite and now it works PERFECTLY!

You code and you learn. Thanks guys!

Lesson learned. Always use digital write when possible.

Go Up