Wrong delay on PORTD,3

Is there anyone who can give an explanation. Why I get a longer delay sometimes on PORTD,3 Normal delay should be 26 uS but sometimes 32 uS between high and low. I use a logic analyzer 10 mhz to test portd,3

int _1_bit_delay = 82;

void setup() {
// put your setup code here, to run once:
DDRD = B00001000; // all indput
bitSet(PORTD, 3);
}

void loop() {
// put your main code here, to run repeatedly:
bitSet(PORTD, 3);
_delay_bit(_1_bit_delay);
bitClear(PORTD, 3);
_delay_bit(_1_bit_delay);
}

void _delay_bit(int d_bit){

int i = 0;

while(i < d_bit ){
asm volatile("nop");
i++;
}
}

Use a micros() based TIMER.

The resolution for micros() is 4 microseconds on all 16MHz Arduino boards: Uno, Mega, Nano, etc.

There are things happening in the background, such as millis(), will interrupt things every now and then.

I always forget that main() is hidden, and does more than just call setup() once, then loop() over and over.

So the problem @LarryD points out is, um, a problem.

Try leaving out the hidden main(), and replace the line of code I quoted above with exactly

int main()
{
  setup();

  while (1)
    myLoop();
}

void myLoop() {

That renames the loop() you wrote, and supplies your own main(), which then calls your myLoop() over and over.

And know that some things the real main() makes work won't. Work.

But it should yield consistent timing of the pulse.

a7

I have tried first using timer micros() but there were even more delay errors. So I chose to make my own function delay but still sometimes get the error delay of 32 uS

Was pointing out what you are doing is blocking code, that’s all.


If you want a non blocking delay period, you need cli/sei to control interrupts, however, this screws up other things.


Arduino helps out:

#define interrupts()     sei()
#define noInterrupts()   cli()

If timing is ultra critical, drop the setup/loop as suggested, code for a hardware timer, and squeeze the juice out that way.

I try you code but get the same error

int _1_bit_delay = 82;

int main()
{
setup();

while (1)
myLoop();
}

void setup() {
// put your setup code here, to run once:
DDRD = B00001000; // all indput
bitSet(PORTD, 3);

}

void myLoop() {
// put your main code here, to run repeatedly:
bitSet(PORTD, 3);
_delay_bit(_1_bit_delay);
bitClear(PORTD, 3);
_delay_bit(_1_bit_delay);
}

void _delay_bit(int d_bit){

int i = 0;

while(i < d_bit ){
asm volatile("nop");
i++;
}
}

OK, I got nothing to add. Sry.

Except - please use the </> tool when you post code and

please use the Auto Format tool in the IDE before you do.

I'll think about why I was wrong or what is goink on.

int _1_bit_delay = 82;

int main()
{
  setup();

  while (1)
    myLoop();
}

void setup() {
  DDRD = B00001000; // all indput
  bitSet(PORTD, 3);

}

void myLoop() {
  bitSet(PORTD, 3);
  _delay_bit(_1_bit_delay);
  bitClear(PORTD, 3);
  _delay_bit(_1_bit_delay);
}

void _delay_bit(int d_bit) {

  int i = 0;

  while (i < d_bit ) {
    asm volatile("nop");
    i++;
  }
}

a7

1 Like

I try hope it's working

int _1_bit_delay = 82;

int main()
{
  setup();

  while (1)
    myLoop();
}

void setup() {
  // put your setup code here, to run once:
DDRD = B00001000;                          // all indput
bitSet(PORTD, 3);

}

void myLoop() {
  // put your main code here, to run repeatedly:
bitSet(PORTD, 3);
_delay_bit(_1_bit_delay);
bitClear(PORTD, 3);
_delay_bit(_1_bit_delay);
}

void _delay_bit(int d_bit){

 int i = 0;

 while(i < d_bit ){
 asm volatile("nop");
 i++;
 }
}

The discrepancy has been accounted for as mentioned above.


Why are you needing exact timing ?

Yes, I think so.

But why did not cutting out real main() suffice? Where are those pesky background tasks started?

a7

delay 26 uS between bitread I have made my own serial function speed 38400. Because I can't use Softwareserial in my sketch.

Use an Arduino with more than one hardware UART. No headaches or mysteries.

a7

1 Like

It is not the hardware UART that is the problem. I'm writing a sketch where I have some "while" run with timeout so I can't even use interrupt or software serial, it causes too many delays in my sketch

const int rxPin = 2;    // the number of the LED pin
const int txPin = 4;    // the number of the LED pin

int _1_bit_delay = 82;
int _1h_bit_delay = 108;


//DDRC = B11101110; 
bool timeout = false;
bool flag_ok = false;


void test_syn();
void test_idle();
void _delay_bit(int);

//ISR(TIMER1_COMPA_vect)
//{
  //timeout = true;
//}  

void setup() {
 
  Serial.begin(115200);
  DDRD = B00001000;                          // all indput
  bitSet(PORTD, 3);
  pinMode(rxPin, INPUT);
  digitalWrite(rxPin, HIGH);

  //cli(); // disable interrupts during setup
  TCCR1A = 0;
  TCCR1B = 0;
  TCCR1B = 0<<WGM12 | 0<<CS12 | 0<<CS11 | 1<<CS10;
  TCNT1 = 0;          // reset Timer 1 counter
  TIMSK1 = 1<<OCIE1A; // Enable Timer 1 interrupt
  //sei(); // re-enable interrupts

}

void loop() {


//bitSet(PORTD, 3);


test_syn();

if(flag_ok == true)
test_idle();

if(flag_ok == true)
Serial.write(0x77);

}

void _delay_bit(int d_bit){

 int i = 0;

 while(i < d_bit ){
 asm volatile("nop");
 i++;
 }
}

void test_syn(){
  
flag_ok = false;
int i = 0;

TCNT1 = 22500;          // timeout 2.7 ms
bitSet(TIFR1, TOV1);      //clear TOV1 flag by putting HIGH at this bit position


while(bitRead(TIFR1, TOV1) != HIGH)
{ 
      bitClear(PORTD, 3);
      while(bitRead(PIND,rxPin) == 0)            // wait for rx line go hig
      {
      if(bitRead(TIFR1, TOV1) == HIGH)
      break;
      }

      while(bitRead(PIND,rxPin) == 1)               // wait for rx line go low for start bit of byte
      {
      if(bitRead(TIFR1, TOV1) == HIGH)
      break;
      }
  
  //bitClear(PORTD, 3);

   
      if(bitRead(TIFR1, TOV1) == HIGH)
      break;                                // timeout exit while
    
      _delay_bit(_1h_bit_delay);            // wait 1.5 bit time to center
      int d = 0;

      for (int j=8; j > 0; --j)             // recive 8 bit
      {                 
      bitSet(PORTD, 3);
      d >>= 1;
    
      if(bitRead(PIND,rxPin) == 1)
      d |= 0x80;
        
      bitClear(PORTD, 3);
      _delay_bit(_1_bit_delay);      // wait 1 bit time
       
      }
     //Serial.write(d);
    

    if(d == 0x55)                   // if 0x55 count up need 3 x 0x55
        i++;      
    else
        i = 0;                       // reset syn word counter
            
    //Serial.write(i);
    if (i == 3){                     // Test if 3 syn word in row are recive 
    flag_ok = true;
    break;
    }
    
 }
 bitSet(PORTD, 3);
}


void test_idle(){

flag_ok = false;
int i = 0;

TCNT1 = 22500;             // timeout 2.7 ms
bitSet(TIFR1, TOV1);      //clear TOV1 flag by bitset

while(bitRead(TIFR1, TOV1) != HIGH)
{

  i = 0;
  while(bitRead(PIND,rxPin) == 1){
    
    i++;
    bitClear(PORTD, 3);
    if(i > 200){
    flag_ok = true;                       // ilde ok
    break;
    }       
  
    //if(timeout == true)
    if(bitRead(TIFR1, TOV1) == HIGH)
    break;
  }
   bitSet(PORTD, 3);
   if(flag_ok == true )
   break;
}

}


@2000nico2000 how often/regularly does the badly timed pulse come along?

I am unable to recreate your results. I am using a cheap 24 MHz logic analyzer and TBH can't see the problem no matter the use of personal main() or no.

But it is like looking for a needle in a pinstack.

a7

Have tried disconnecting the USB and using a different power supply for the nano board. now there is no delay error in my pulse sketch. But the error is still there in my second setup. Where I use two nano board one to simulate some signal, the other I am writing a sketch to capture signal from it first. I have common GND for both nano boards. I have tried a different power supply for that setup. Still the same problem. Still longer delay than expected sometimes. I use function delay between bitRead. I finish writing my sketch and see if it can work without errors. Thanks for trying to help me.

Which version? Let us call one "Arduino main" and the other " custom main".

And please answer this question

Now you are describing in words a somewhat complex experiment, involving multiple boards which implies multiple sketches.

Please draw a diagram and post all code for any experiments. Post results in detail, including anything that woukd help anyone repeating your tests.

What instruments are you using? Has some feature or shortcoming of them, or your own ability to use them, been ruled out?

TIA

a7

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.