Go Down

Topic: SERIAL losses first few symbols during transmission WHEN interrupt initialized (Read 375 times) previous topic - next topic

alexblade

When the modem receives a call then 2 things are happening:
a) on modem Pin 10 is LOW level which I catch by INT0
b) modem send to leonardo board the string "number data time etc." > leonardo send to PC

so I made this code for debug, and especial have used PORT writing since it 20x faster then digitalWrite, but anyway I loose first few symbols from serial transmit

Code: [Select]
//Serial modem > leonardo > PC

volatile byte flag = 0;

void setup(){
  pinMode(13, OUTPUT);
  pinMode(3, INPUT); //low level from modem for INT0
  while(!Serial); // for leonardo
  Serial.begin(115200);
  Serial1.begin(115200);
  attachInterrupt(0, blink, LOW);

  }

void loop(){
  // Копируем Serial1 --> Serial
  if(Serial1.available()) Serial.write(Serial1.read());
  // Копируем Serial --> Serial1
  if(Serial.available()) Serial1.write(Serial.read());

  if (flag) {
  PORTC |= (1 << 7);
  flag = 0;
  }

}

void blink() {
flag = 1;
}



any idea?   or how to make this code more faster to catch all symbols OR how to change the algorithm to catch all symbols. please help

Idahowalker

I use
Code: [Select]
void fReceiveSerial_LIDAR( void * parameters  )
{
  bool BeginSentence = false;
  sSerial.reserve ( StringBufferSize300 );
  char OneChar;
  for ( ;; )
  {
    EventBits_t xbit = xEventGroupWaitBits (eg, evtReceiveSerial_LIDAR, pdTRUE, pdTRUE, portMAX_DELAY);
    if ( LIDARSerial.available() >= 1 )
    {
      while ( LIDARSerial.available() )
      {
        OneChar = LIDARSerial.read();
        if ( BeginSentence )
        {
          if ( OneChar == '>')
          {
            if ( xSemaphoreTake( sema_ParseLIDAR_ReceivedSerial, xSemaphoreTicksToWait10 ) == pdTRUE )
            {
              xQueueOverwrite( xQ_LIDAR_Display_INFO, ( void * ) &sSerial );
              xEventGroupSetBits( eg, evtParseLIDAR_ReceivedSerial );
            }
            BeginSentence = false;
            break;
          }
          sSerial.concat ( OneChar );
        }
        else
        {
          if ( OneChar == '<' )
          {
            sSerial = ""; // clear string buffer
            BeginSentence = true; // found begining of sentence
          }
        }
      } //  while ( LIDARSerial.available() )
    } //if ( LIDARSerial.available() >= 1 )
    xSemaphoreGive( sema_ReceiveSerial_LIDAR );

  }
  vTaskDelete( NULL );
} //void fParseSerial( void * parameters  )
This line "if ( LIDARSerial.available() >= 1 )" before entering the while loop since trying to receive serial on  the Due, STM32, and ESP32. Using  "if ( LIDARSerial.available() >0  )" caused receive data loss.

I also send sentence delimiters and discard the non complete sentences. In addition, once the sentence beginning has been received, I do not delete the receive buffer, even if the loop exits and reenters, until a new sentence descriptor is received. I am receiving around 255 words per sentence.

alexblade

"if ( LIDARSerial.available() >= 1 )" before entering the while loop since trying to receive serial on  the Due, STM32, and ESP32. Using  "if ( LIDARSerial.available() >0  )" caused receive data loss.
I cant imagine this :) why, should be some logical explain
BUT anyway, even if I make while instead of if, I think this is not applicable to my case because

a) if INT0 triggered doesnt matter what I have while/if
b) INT0 fired at the same time when serial.available>0. both things start at the same time

Whandall

Code: [Select]
  pinMode(3, INPUT); //low level from modem for INT0
  attachInterrupt(0, blink, LOW);


If your modem is connected to pin 3, why do you hook the interrupt to pin 2?
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

gfvalvo

If your modem is connected to pin 3, why do you hook the interrupt to pin 2?
@alexblade, there's already a mechanism for avoiding this careless mistake: digitalPinToInterrupt()
Why don't you use it?
No technical questions via PM. They will be ignored. Post your questions in the forum so that all may learn.

gfvalvo

Be careful of level-triggered interrupts. They will fire continuously as long as the condition is true. That can eat up a lot of processor time. Why do you need an interrupt to capture your "modem pin" going low? Why not use polling and the state change example from the IDE?

If you MUST use an interrupt, first choice would be edge-triggered (FALLING). If you MUST use a level-triggered interrupt, then disable the interrupt in the ISR and don't re-enable it in the main code until the input goes HIGH again.
No technical questions via PM. They will be ignored. Post your questions in the forum so that all may learn.

alexblade

If your modem is connected to pin 3, why do you hook the interrupt to pin 2?
because this is Leonardo board (its mentioned in post 1 :)

gfvalvo, to honest say I want to like train low level understanding/coding...  but in this particular case mentioned pin is not mistake. I can write digitalPinToInterrupt() and still losing characters

@Be careful of level-triggered interrupts. They will fire continuously as long as the condition is true.@
hm I dont know this thank you, but any way I'm usually using  or millis or detach to avoid bounce

gfvalvo

@Be careful of level-triggered interrupts. They will fire continuously as long as the condition is true.@
hm I dont know this thank you, but any way I'm usually using  or millis or detach to avoid bounce
I don't know what that means and it's not what's shown in the code you posted. But, suit yourself.
No technical questions via PM. They will be ignored. Post your questions in the forum so that all may learn.

alexblade

gfvalvo,
detach means
ISR(){
detachInterrupt();
state=!state;
}

millis mean
ISR(){
  static unsigned long millis_prev;
  if(millis()-100 > millis_prev) state = !state;   // меняем значение на противоположное
  millis_prev = millis();   
}

but i the code I posted led can blinking as long as want doesnt matter, blink is needed just to see if I    caught the INT0

main idea in the code to show how I send data serial to PC.  and problem in the post 1
have you any idea?

gfvalvo

have you any idea?
Yes, I have some Ideas:

* Post the ACTUAL code that's causing the problem you're talking about.

* Post the COMPLETE code.

* Post the code properly with CODE TAGS.

No technical questions via PM. They will be ignored. Post your questions in the forum so that all may learn.

alexblade

gfvalvo? this is ctrlC ctrlV complete code :) with code tags . POST1

when modem send data (and in this time ISR fired)  then first few 5-10 symbols is missing from transmit.
if comment interrupt (disable part of code) then I dont see led blink but see all data in serial port

gfvalvo

No technical questions via PM. They will be ignored. Post your questions in the forum so that all may learn.

alexblade

this code like debug.
INT0 is needed to monitor state of modem pin 10
serial is needed to monitor state of modem pin 7

gfvalvo

You aren't providing any answers that make sense. I'm done wasting my time. Good luck.
No technical questions via PM. They will be ignored. Post your questions in the forum so that all may learn.

alexblade

Why do you need an interrupt to monitor Modem Pin 10?
because low level is on pin 10 only 30ms when incoming call is.

I do not have other instruments check if it was LOW and if it was in generally sometime. if you know please advise

Go Up