Serial transmission on Uno hangs

Hi,

Looked all over forums, couldn't find same problem:

Trying to add send functionality to the following:

This code can read the serial input from digital pin 2 on Arduino Uno.

I use this library for transmission:

I have modified the send function as I only need to transfer message bytes:

  byte message[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}; // LEDs ON
  uint8_t cksum = dataChecksum(message,8,0x32);
  serial.write(message, 8);  // data bytes
  serial.write(cksum);  // checksum
}

I have added the send function to arduino.ino file from first repository:

#include "action_led.h"
#include "avr_util.h"
#include "custom_defs.h"
#include "hardware_clock.h"
#include "io_pins.h"
#include "lin_processor.h"
#include "system_clock.h"
#include "lin.h"

Lin lin;

// FRAMES LED - blinks when detecting valid frames.
static ActionLed frames_activity_led(PORTB, 0);

// ERRORS LED - blinks when detecting errors.
static ActionLed errors_activity_led(PORTB, 1);




// Arduino setup function. Called once during initialization.
void setup()
{
  // Hard coded to 115.2k baud. Uses URART0, no interrupts.
  // Initialize this first since some setup methods uses it.
  digitalWrite(13, HIGH);
  // Uses Timer1, no interrupts.
  hardware_clock::setup();

  // Uses Timer2 with interrupts, and a few i/o pins. See source code for details.
  lin_processor::setup();
  
  // Enable global interrupts. We expect to have only timer1 interrupts by
  // the lin processor to reduce ISR jitter.
  sei(); 
  
  // Have an early 'waiting' led bling to indicate normal operation.
  frames_activity_led.action(); 

  lin.begin(19200);
}

// Arduino loop() method. Called after setup(). Never returns.
// This is a quick loop that does not use delay() or other busy loops or 
// blocking calls.
void loop()
{
  // Having our own loop shaves about 4 usec per iteration. It also eliminate
  // any underlying functionality that we may not want.
  for(;;) {  
    system_clock::loop();    


    // Print a periodic text messages if no activiy.
    static PassiveTimer idle_timer;
    if (idle_timer.timeMillis() >= 3000) {
      idle_timer.restart();
    }

    // Handle LIN processor error flags.
    {
      // Used to trigger periodic error printing.
      static PassiveTimer lin_errors_timeout;
      // Accomulates error flags until next printing.
      static uint8 pending_lin_errors = 0;
      
      const uint8 new_lin_errors = lin_processor::getAndClearErrorFlags();
      if (new_lin_errors) {
        // Make the ERRORS led blinking.
        errors_activity_led.action();
        idle_timer.restart();
      }

      // If pending errors and time to print errors then print and clear.
      pending_lin_errors |= new_lin_errors;
      if (pending_lin_errors && lin_errors_timeout.timeMillis() > 1000) {
        lin_errors_timeout.restart();
        pending_lin_errors = 0;
      }
    }
    

    // Handle recieved LIN frames.
    LinFrame frame;
    if (lin_processor::readNextFrame(&frame)) { 
      const boolean frameOk = frame.isValid();
      if (frameOk) {
           lin.send(frame.num_bytes());
      } 
      else {

      }

      idle_timer.restart(); 
    }
    }
  
}

I have another board which is sending request messages (detected by lin_processor.cpp) to the arduino. Then it waits for the response from arduino which is the 8 bytes "message" (sent by "send" function and sends another request. I can see on oscilloscope that the messages are received correctly on arduino side, which means if (frameOk) is true and then the send function is executed and message bytes are sent). However, after a while the tx pin on arduino gets stuck at 1 and doesn't transmit anymore (again visible from oscilloscope). I can not figure out why this happens? Is there anything I should do to empty the transmit buffer or so?

Thanks

Provide more information about what hardware you're using. The receiving code expects the LIN bus to be read from pin3 and originally sends out on A2. The Lin library you linked to uses the hardware serial interface to send the LIN messages.
Also using the linked library (LIN) the sketch won't compile as there is no send() method with one parameter.

I have compiled the code from first repository on arduino uno and use following for tranciever:
http://skpang.co.uk/catalog/linbus-breakout-board-p-1417.html
Not sure what else to add about hw? I tried but I can't attach an image from my setup here.

I don't know from which file you point to pin3. It uses pin D2 which on arduino uno it is digital pin 2.
I know "The Lin library you linked to uses the hardware serial interface to send the LIN messages.", but I just use transmit function from serial hw which is digital pin 1. Reading is done on digital pin 2 by first repositrory's code.
The header file for lin send should change as well according, I have not included it here since it doesn't make any difference. But here you go for convenience:

void send(uint8_t nBytes);

Not sure what else to add about hw?

A wiring diagram.

I don’t know from which file you point to pin3. It uses pin D2 which on arduino uno it is digital pin 2.

That was a type, please excuse. I meant D2.

The header file for lin send should change as well according, I have not included it here since it doesn’t make any difference. But here you go for convenience:

That’s not in the library you linked. What does that send? Nothing? Did you change the LIN library? If yes, why did you link to the original library instead of providing the code you’re actually using? Please don’t waste our time.

As I explained I use the second library to add extra functionality (sending LIN messages) to the first library (which is only a analyzer/sniffer). So the only thing one need to do is to copy the lin.cpp and lin.h from second library in first, and change the "send" function as explained, both in lin.h and lin.cpp files. I didn't know I have to explain this (seemed obvious to me), no intention to waste anyone's time.
I can't seem to attach any kind of file! I have written to moderator, no response yet.
Here the code for changed send function in lin.cpp (change in lin.h is found in previous message):

void Lin::send(uint8_t nBytes)//(uint8_t addr, const uint8_t* message, uint8_t nBytes,uint8_t proto)
{
  byte message[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}; // LEDs ON
  uint8_t cksum = dataChecksum(message,8,0x32);
  serial.write(message, 8);  // data bytes
  serial.write(cksum);  // checksum
}

If you had posted the complete send method as above in your first post it would have been much clearer what code you're using.

You know that the message you're sending is not a LIN message? You don't even send the break signal. Why do you use the LIN library at all? You don't use any service except the Checksum calculation but that results in a fixed value anyway.

The messages are sent only if correct frames are received but as you're inserting incorrect frames you may prohibit exactly that.

What exactly is that other board doing? Is it conforming to the LIN standard? If yes, the above may exactly be your problem.

But my arduino is working as a slave so when it receives the specific ID (0x32), as slave, it sends the data back. I don't understand why the slave needs to send break signal? Isn't master responsible for sending that? (Which is the other board I have, a TI hercules). The master sends a header (break + sync + ID). The analyzer code detects it as a LIN message. And then it responds with data and checksum with my modified send method. Unless I have understood LIN protocol completely wrong?

You haven't expressed yet, if your Arduino is master or slave in the communication. If I re-read your first post, there are some hints in the direction that it might act as a slave but I thought of it being kind of filter device that reads the masters requests and sends it modified to some slave. I thought this because your using the analyzer sketch of the first library and because you're using the second library which is a library for the master (although you're not really using it). I should have asked for clarification.

Please define clearly what you're trying to achieve, how your Arduino is expected to behave in the network and if you're trying to emulate something.

I would insert some code that sets some pin high if a request is received and low again if it's answered. This way you can see if your Arduino is still working. Check in what state that pin is if the Arduino stops sending out responses. This way you may approach the problem. I guess a memory problem or interrupt dead lock. The analyzer code makes quite excessive use of interrupt disabling which is not good if you use the hardware serial interface.

The Arduino is slave. I use the analyzer part to detect LIN frames and second library modified to send LIN responses. I have a TI hercules board which acts as Master. It sends request, waits for response and sends another request. This means I can't have a rx buffer overflow on Arduino. I can see this happening using the oscilloscope. Many transitions of request/response, then all of a sudden it stops. And after different number of requests (i.e. once after ten transmission next time after 500).
I already check the tx pin of arduino being stuck at one when transmission stops, and then if I send a new request, it responds (without resetting the arduino).

I also guessed it to be an interrupt issue, but since I am not sending anything before receiving previous response it can't be a rx interrupt, unless there are other interrupts coming from somewhere else (which I don't see where)? I thought someone with more experience might have a a clue.

Thanks

I also guessed it to be an interrupt issue, but since I am not sending anything before receiving previous response it can't be a rx interrupt, unless there are other interrupts coming from somewhere else (which I don't see where)? I thought someone with more experience might have a a clue.

The Arduino framework installs a timer interrupt to enable the millis() and micros() calls. So the code is interrupted once a millisecond but that is quite short and some delay shouldn't really influence your code. The problem is that the analyzer code is rather over-complex for your task and the completely unnecessary second library doesn't help too.

Have you tried my suggestion with the additional pin?

You can also try to activate the watchdog, it will reset your board if the code freezes. This doesn't fix the errors in the code but might help you get it working for some time. I would try to debug the errors but I don't know how much time you're willing to invest in your project. It might be a good idea to write your own LIN slave library to eliminate the unneeded analyzer code in your current setup.