Skip to main content
added 334 characters in body; added 14 characters in body
Source Link
Jot
  • 3.3k
  • 1
  • 14
  • 21

When you say that something is working for sure, then there is a big chance that the problem is in that part. If the problem was somewhere else, then perhaps you could find the problem yourself.

Interrupts are executed one after another (with a few exceptions). Things run smooth when all interrupt routines are as short and as fast as possible. You have no control over the interrupt routine of the serial communication in the Serial library, but at least your own interrupt function should be as short as possible.

Please show us a sketch that has the problem. You have removed the most important part.
If for example your interrupt function calls a Serial function, then it can go wrong because the Serial library uses interrupts itself. If your interrupt function takes longer than the interrupts from receiving data at 115200 baud, then characters could be missed. The keyword 'volatile' should be used in a proper way. The Arduino Mega has a 8-bit microcontroller, that means that when handling an 16-bit or 32-bit variable an interrupt could occur while that variable is read or writting only halfway. And so on, and so on.

Update
You have shown the complete sketch, and the interrupt function 'myFunction' takes a very long time to do all those calculations.

The 'Kr', 'Ti' and 'Td' are written in the loop, and used in 'Myfunction' which is an interrupt routine. They are float variables that are 4 bytes long. That means that 'Myfunction' could be executed when one of those variables are written only halfway. It is better to disable interrupts when writing those variables. To keep disabling the interrupts short, don't disable interrupts when calling .toFloat(). Use temperary variables.

float yref_temporary = yref_str.toFloat();
float Kr_temporary = Kr_str.toFloat();
float Ti_temporary = Ti_str.toFloat();
float Td_temporary = Td_str.toFloat();

noInterrupts();
yref = yref_temporary;
Kr = Kr_temporary;
Ti = Ti_temporary;
Td = Td_temporary;
interrupts();

I think you have to make 'yref' volatile as well.

The Serial input is 115200 baud, that can be an interrupt every 87µs.
The Timer1 Myfunction runs every 50ms.
The Myfunction takes more than 600µs.

I did not measure the timing of 'Myfunction'. I calculated it for a rough number. 5 float divisions = 570µs. 11 float multiply = 117µs. 10 float substractions or additions = 10*7µs. Plus analogRead of 112µs. Plus a few more, that adds up to at least 600µs. It could be about 1ms.

There might be more conflicts.
The baudrate is high, and the Serial.readStringUntil is slow because it uses a String object.
There is no error checking for the received values.
The four .toFloat are always called, even when there was no serial data received.
Printing to the lcd display is also done every time the loop runs. There is no need to update the slow LCD display hundreds of times per second. That could be slowed down with millis.

Conclusion: Your 'Myfunction' is a real interrupt routine. When that is busy, the other interrupts have to wait. Since it takes more than 600µs, the Serial interrupts could be missed.
Perhaps a software timer with millis is accurate enough for the calculations. To be able to use millis, the Serial.readStringUntil can no longer be used.

When you say that something is working for sure, then there is a big chance that the problem is in that part. If the problem was somewhere else, then perhaps you could find the problem yourself.

Interrupts are executed one after another (with a few exceptions). Things run smooth when all interrupt routines are as short and as fast as possible. You have no control over the interrupt routine of the serial communication in the Serial library, but at least your own interrupt function should be as short as possible.

Please show us a sketch that has the problem. You have removed the most important part.
If for example your interrupt function calls a Serial function, then it can go wrong because the Serial library uses interrupts itself. If your interrupt function takes longer than the interrupts from receiving data at 115200 baud, then characters could be missed. The keyword 'volatile' should be used in a proper way. The Arduino Mega has a 8-bit microcontroller, that means that when handling an 16-bit or 32-bit variable an interrupt could occur while that variable is read or writting only halfway. And so on, and so on.

Update
You have shown the complete sketch, and the interrupt function 'myFunction' takes a very long time to do all those calculations.

The 'Kr', 'Ti' and 'Td' are written in the loop, and used in 'Myfunction' which is an interrupt routine. They are float variables that are 4 bytes long. That means that 'Myfunction' could be executed when one of those variables are written only halfway. It is better to disable interrupts when writing those variables. To keep disabling the interrupts short, don't disable interrupts when calling .toFloat(). Use temperary variables.

float yref_temporary = yref_str.toFloat();
float Kr_temporary = Kr_str.toFloat();
float Ti_temporary = Ti_str.toFloat();
float Td_temporary = Td_str.toFloat();

noInterrupts();
yref = yref_temporary;
Kr = Kr_temporary;
Ti = Ti_temporary;
Td = Td_temporary;
interrupts();

I think you have to make 'yref' volatile as well.

The Serial input is 115200 baud, that can be an interrupt every 87µs.
The Timer1 Myfunction runs every 50ms.
The Myfunction takes more than 600µs.

I did not measure the timing of 'Myfunction'. I calculated it for a rough number. 5 float divisions = 570µs. 11 float multiply = 117µs. 10 float substractions or additions = 10*7µs. Plus analogRead of 112µs. Plus a few more, that adds up to at least 600µs. It could be about 1ms.

There might be more conflicts.
The baudrate is high, and the Serial.readStringUntil is slow because it uses a String object.
There is no error checking for the received values.

Conclusion: Your 'Myfunction' is a real interrupt routine. When that is busy, the other interrupts have to wait. Since it takes more than 600µs, the Serial interrupts could be missed.
Perhaps a software timer with millis is accurate enough for the calculations.

When you say that something is working for sure, then there is a big chance that the problem is in that part. If the problem was somewhere else, then perhaps you could find the problem yourself.

Interrupts are executed one after another (with a few exceptions). Things run smooth when all interrupt routines are as short and as fast as possible. You have no control over the interrupt routine of the serial communication in the Serial library, but at least your own interrupt function should be as short as possible.

Please show us a sketch that has the problem. You have removed the most important part.
If for example your interrupt function calls a Serial function, then it can go wrong because the Serial library uses interrupts itself. If your interrupt function takes longer than the interrupts from receiving data at 115200 baud, then characters could be missed. The keyword 'volatile' should be used in a proper way. The Arduino Mega has a 8-bit microcontroller, that means that when handling an 16-bit or 32-bit variable an interrupt could occur while that variable is read or writting only halfway. And so on, and so on.

Update
You have shown the complete sketch, and the interrupt function 'myFunction' takes a very long time to do all those calculations.

The 'Kr', 'Ti' and 'Td' are written in the loop, and used in 'Myfunction' which is an interrupt routine. They are float variables that are 4 bytes long. That means that 'Myfunction' could be executed when one of those variables are written only halfway. It is better to disable interrupts when writing those variables. To keep disabling the interrupts short, don't disable interrupts when calling .toFloat(). Use temperary variables.

float yref_temporary = yref_str.toFloat();
float Kr_temporary = Kr_str.toFloat();
float Ti_temporary = Ti_str.toFloat();
float Td_temporary = Td_str.toFloat();

noInterrupts();
yref = yref_temporary;
Kr = Kr_temporary;
Ti = Ti_temporary;
Td = Td_temporary;
interrupts();

I think you have to make 'yref' volatile as well.

The Serial input is 115200 baud, that can be an interrupt every 87µs.
The Timer1 Myfunction runs every 50ms.
The Myfunction takes more than 600µs.

I did not measure the timing of 'Myfunction'. I calculated it for a rough number. 5 float divisions = 570µs. 11 float multiply = 117µs. 10 float substractions or additions = 10*7µs. Plus analogRead of 112µs. Plus a few more, that adds up to at least 600µs. It could be about 1ms.

There might be more conflicts.
The baudrate is high, and the Serial.readStringUntil is slow because it uses a String object.
There is no error checking for the received values.
The four .toFloat are always called, even when there was no serial data received.
Printing to the lcd display is also done every time the loop runs. There is no need to update the slow LCD display hundreds of times per second. That could be slowed down with millis.

Conclusion: Your 'Myfunction' is a real interrupt routine. When that is busy, the other interrupts have to wait. Since it takes more than 600µs, the Serial interrupts could be missed.
Perhaps a software timer with millis is accurate enough for the calculations. To be able to use millis, the Serial.readStringUntil can no longer be used.

added 128 characters in body; added 58 characters in body
Source Link
Jot
  • 3.3k
  • 1
  • 14
  • 21

When you say that something is working for sure, then there is a big chance that the problem is in that part. If the problem was somewhere else, then perhaps you could find the problem yourself.

Interrupts are executed one after another (with a few exceptions). Things run smooth when all interrupt routines are as short and as fast as possible. You have no control over the interrupt routine of the serial communication in the Serial library, but at least your own interrupt function should be as short as possible.

Please show us a sketch that has the problem. You have removed the most important part.
If for example your interrupt function calls a Serial function, then it can go wrong because the Serial library uses interrupts itself. If your interrupt function takes longer than the interrupts from receiving data at 115200 baud, then characters could be missed. The keyword 'volatile' should be used in a proper way. The Arduino Mega has a 8-bit microcontroller, that means that when handling an 16-bit or 32-bit variable an interrupt could occur while that variable is read or writting only halfway. And so on, and so on.

Update
You have shown the complete sketch, and the interrupt function 'myFunction' takes a very long time to do all those calculations.

The 'Kr', 'Ti' and 'Td' are written in the loop, and used in 'Myfunction' which is an interrupt routine. They are float variables that are 4 bytes long. That means that 'Myfunction' could be executed when one of those variables are written only halfway. It is better to disable interrupts when writing those variables. To keep disabling the interrupts short, don't disable interrupts when calling .toFloat(). Use temperary variables.

float yref_temporary = yref_str.toFloat();
float Kr_temporary = Kr_str.toFloat();
float Ti_temporary = Ti_str.toFloat();
float Td_temporary = Td_str.toFloat();

noInterrupts();
yref = yref_temporary;
Kr = Kr_temporary;
Ti = Ti_temporary;
Td = Td_temporary;
interrupts();

I think you have to make 'yref' volatile as well.

The Serial input is 115200 baud, that can be an interrupt every 87µs.
The Timer1 Myfunction runs every 50ms.
The Myfunction takes more than 600µs.

I did not measure the timing of 'Myfunction'. I calculated it for a rough number. 5 float divisions = 570µs. 11 float multiply = 117µs. 10 float substractions or additions = 10*7µs. Plus analogRead of 112µs. Plus a few more, that adds up to at least 600µs. It could be about 1ms.

There might be more conflicts.
The baudrate is high, and the Serial.readStringUntil is slow because it uses a String object.
There is no error checking for the received values.

Conclusion: Your 'Myfunction' is a real interrupt routine. When that is busy, the other interrupts have to wait. Since it takes more than 600µs, the Serial interrupts could be missed.
Perhaps a software timer with millis is accurate enough for the calculations.

When you say that something is working for sure, then there is a big chance that the problem is in that part. If the problem was somewhere else, then perhaps you could find the problem yourself.

Interrupts are executed one after another (with a few exceptions). Things run smooth when all interrupt routines are as short and as fast as possible. You have no control over the interrupt routine of the serial communication in the Serial library, but at least your own interrupt function should be as short as possible.

Please show us a sketch that has the problem. You have removed the most important part.
If for example your interrupt function calls a Serial function, then it can go wrong because the Serial library uses interrupts itself. If your interrupt function takes longer than the interrupts from receiving data at 115200 baud, then characters could be missed. The keyword 'volatile' should be used in a proper way. The Arduino Mega has a 8-bit microcontroller, that means that when handling an 16-bit or 32-bit variable an interrupt could occur while that variable is read or writting only halfway. And so on, and so on.

Update
You have shown the complete sketch, and the interrupt function 'myFunction' takes a very long time to do all those calculations.

The 'Kr', 'Ti' and 'Td' are written in the loop, and used in 'Myfunction' which is an interrupt routine. They are float variables that are 4 bytes long. That means that 'Myfunction' could be executed when one of those variables are written only halfway. It is better to disable interrupts when writing those variables. To keep disabling the interrupts short, don't disable interrupts when calling .toFloat(). Use temperary variables.

float yref_temporary = yref_str.toFloat();
float Kr_temporary = Kr_str.toFloat();
float Ti_temporary = Ti_str.toFloat();
float Td_temporary = Td_str.toFloat();

noInterrupts();
yref = yref_temporary;
Kr = Kr_temporary;
Ti = Ti_temporary;
Td = Td_temporary;
interrupts();

I think you have to make 'yref' volatile as well.

The Serial input is 115200 baud, that can be an interrupt every 87µs.
The Timer1 Myfunction runs every 50ms.
The Myfunction takes more than 600µs.

I did not measure the timing of 'Myfunction'. I calculated it for a rough number. 5 float divisions = 570µs. 11 float multiply = 117µs. 10 float substractions or additions = 10*7µs. Plus analogRead of 112µs. Plus a few more, that adds up to at least 600µs. It could be about 1ms.

Conclusion: Your 'Myfunction' is a real interrupt routine. When that is busy, the other interrupts have to wait. Since it takes more than 600µs, the Serial interrupts could be missed.
Perhaps a software timer with millis is accurate enough for the calculations.

When you say that something is working for sure, then there is a big chance that the problem is in that part. If the problem was somewhere else, then perhaps you could find the problem yourself.

Interrupts are executed one after another (with a few exceptions). Things run smooth when all interrupt routines are as short and as fast as possible. You have no control over the interrupt routine of the serial communication in the Serial library, but at least your own interrupt function should be as short as possible.

Please show us a sketch that has the problem. You have removed the most important part.
If for example your interrupt function calls a Serial function, then it can go wrong because the Serial library uses interrupts itself. If your interrupt function takes longer than the interrupts from receiving data at 115200 baud, then characters could be missed. The keyword 'volatile' should be used in a proper way. The Arduino Mega has a 8-bit microcontroller, that means that when handling an 16-bit or 32-bit variable an interrupt could occur while that variable is read or writting only halfway. And so on, and so on.

Update
You have shown the complete sketch, and the interrupt function 'myFunction' takes a very long time to do all those calculations.

The 'Kr', 'Ti' and 'Td' are written in the loop, and used in 'Myfunction' which is an interrupt routine. They are float variables that are 4 bytes long. That means that 'Myfunction' could be executed when one of those variables are written only halfway. It is better to disable interrupts when writing those variables. To keep disabling the interrupts short, don't disable interrupts when calling .toFloat(). Use temperary variables.

float yref_temporary = yref_str.toFloat();
float Kr_temporary = Kr_str.toFloat();
float Ti_temporary = Ti_str.toFloat();
float Td_temporary = Td_str.toFloat();

noInterrupts();
yref = yref_temporary;
Kr = Kr_temporary;
Ti = Ti_temporary;
Td = Td_temporary;
interrupts();

I think you have to make 'yref' volatile as well.

The Serial input is 115200 baud, that can be an interrupt every 87µs.
The Timer1 Myfunction runs every 50ms.
The Myfunction takes more than 600µs.

I did not measure the timing of 'Myfunction'. I calculated it for a rough number. 5 float divisions = 570µs. 11 float multiply = 117µs. 10 float substractions or additions = 10*7µs. Plus analogRead of 112µs. Plus a few more, that adds up to at least 600µs. It could be about 1ms.

There might be more conflicts.
The baudrate is high, and the Serial.readStringUntil is slow because it uses a String object.
There is no error checking for the received values.

Conclusion: Your 'Myfunction' is a real interrupt routine. When that is busy, the other interrupts have to wait. Since it takes more than 600µs, the Serial interrupts could be missed.
Perhaps a software timer with millis is accurate enough for the calculations.

Oops, the Timer1 runs at 50ms.; added 4 characters in body; added 81 characters in body
Source Link
Jot
  • 3.3k
  • 1
  • 14
  • 21

When you say that something is working for sure, then there is a big chance that the problem is in that part. If the problem was somewhere else, then perhaps you could find the problem yourself.

Interrupts are executed one after another (with a few exceptions). Things run smooth when all interrupt routines are as short and as fast as possible. You have no control over the interrupt routine of the serial communication in the Serial library, but at least your own interrupt function should be as short as possible.

Please show us a sketch that has the problem. You have removed the most important part.
If for example your interrupt function calls a Serial function, then it can go wrong because the Serial library uses interrupts itself. If your interrupt function takes longer than the interrupts from receiving data at 115200 baud, then characters could be missed. The keyword 'volatile' should be used in a proper way. The Arduino Mega has a 8-bit microcontroller, that means that when handling an 16-bit or 32-bit variable an interrupt could occur while that variable is read or writting only halfway. And so on, and so on.

Update
You have shown the complete sketch, and the interrupt function 'myFunction' is called far to often, and takes takes a very long time to do all those calculations.

The 'Kr', 'Ti' and 'Td' are written in the loop, and used in 'Myfunction' which is an interrupt routine. They are float variables that are 4 bytes long. That means that 'Myfunction' could be executed when one of those variables are written only halfway. It is better to disable interrupts when writing those variables. To keep disabling the interrupts short, don't disable interrupts when calling .toFloat(). Use temperary variables.

float yref_temporary = yref_str.toFloat();
float Kr_temporary = Kr_str.toFloat();
float Ti_temporary = Ti_str.toFloat();
float Td_temporary = Td_str.toFloat();

noInterrupts();
yref = yref_temporary;
Kr = Kr_temporary;
Ti = Ti_temporary;
Td = Td_temporary;
interrupts();

I think you have to make 'yref' volatile as well.

The Serial input is 115200 baud, that can be an interruptsinterrupt every 87µs.
The Timer1 Myfunction runs every 20µs50ms.
The Myfunction takes more than 600µs.
It's amazing that your sketch is doing something at all.

I did not measure the timing of 'Myfunction'. I calculated it for a rough number. 5 float divisions = 570µs. 11 float multiply = 117µs. 10 float substractions or additions = 10*7µs. Plus analogRead of 112µs. Plus a few more, that adds up to at least 600µs. It could be about 1ms.

Conclusion: You can not even do those calculations 1000 times a second, and 50000 timesYour 'Myfunction' is a secondreal interrupt routine. When that is way too fastbusy, the other interrupts have to wait. Since it takes more than 600µs, the analogWrite isSerial interrupts could be missed.
Perhaps a PWM signal of about 500Hz, why do you want to update that so many times ?software timer with millis is accurate enough for the calculations.

When you say that something is working for sure, then there is a big chance that the problem is in that part. If the problem was somewhere else, then perhaps you could find the problem yourself.

Interrupts are executed one after another (with a few exceptions). Things run smooth when all interrupt routines are as short and as fast as possible. You have no control over the interrupt routine of the serial communication in the Serial library, but at least your own interrupt function should be as short as possible.

Please show us a sketch that has the problem. You have removed the most important part.
If for example your interrupt function calls a Serial function, then it can go wrong because the Serial library uses interrupts itself. If your interrupt function takes longer than the interrupts from receiving data at 115200 baud, then characters could be missed. The keyword 'volatile' should be used in a proper way. The Arduino Mega has a 8-bit microcontroller, that means that when handling an 16-bit or 32-bit variable an interrupt could occur while that variable is read or writting only halfway. And so on, and so on.

Update
You have shown the complete sketch, and the interrupt function 'myFunction' is called far to often, and takes a very long time to do all those calculations.

The 'Kr', 'Ti' and 'Td' are written in the loop, and used in 'Myfunction' which is an interrupt routine. They are float variables that are 4 bytes long. That means that 'Myfunction' could be executed when one of those variables are written only halfway. It is better to disable interrupts when writing those variables. To keep disabling the interrupts short, don't disable interrupts when calling .toFloat(). Use temperary variables.

float yref_temporary = yref_str.toFloat();
float Kr_temporary = Kr_str.toFloat();
float Ti_temporary = Ti_str.toFloat();
float Td_temporary = Td_str.toFloat();

noInterrupts();
yref = yref_temporary;
Kr = Kr_temporary;
Ti = Ti_temporary;
Td = Td_temporary;
interrupts();

I think you have to make 'yref' volatile as well.

The Serial input is 115200 baud, that can be an interrupts every 87µs.
The Timer1 Myfunction runs every 20µs.
The Myfunction takes more than 600µs.
It's amazing that your sketch is doing something at all.

I did not measure the timing of 'Myfunction'. I calculated it for a rough number. 5 float divisions = 570µs. 11 float multiply = 117µs. 10 float substractions or additions = 10*7µs. Plus analogRead of 112µs. Plus a few more, that adds up to at least 600µs. It could be about 1ms.

Conclusion: You can not even do those calculations 1000 times a second, and 50000 times a second is way too fast. Since the analogWrite is a PWM signal of about 500Hz, why do you want to update that so many times ?

When you say that something is working for sure, then there is a big chance that the problem is in that part. If the problem was somewhere else, then perhaps you could find the problem yourself.

Interrupts are executed one after another (with a few exceptions). Things run smooth when all interrupt routines are as short and as fast as possible. You have no control over the interrupt routine of the serial communication in the Serial library, but at least your own interrupt function should be as short as possible.

Please show us a sketch that has the problem. You have removed the most important part.
If for example your interrupt function calls a Serial function, then it can go wrong because the Serial library uses interrupts itself. If your interrupt function takes longer than the interrupts from receiving data at 115200 baud, then characters could be missed. The keyword 'volatile' should be used in a proper way. The Arduino Mega has a 8-bit microcontroller, that means that when handling an 16-bit or 32-bit variable an interrupt could occur while that variable is read or writting only halfway. And so on, and so on.

Update
You have shown the complete sketch, and the interrupt function 'myFunction' takes a very long time to do all those calculations.

The 'Kr', 'Ti' and 'Td' are written in the loop, and used in 'Myfunction' which is an interrupt routine. They are float variables that are 4 bytes long. That means that 'Myfunction' could be executed when one of those variables are written only halfway. It is better to disable interrupts when writing those variables. To keep disabling the interrupts short, don't disable interrupts when calling .toFloat(). Use temperary variables.

float yref_temporary = yref_str.toFloat();
float Kr_temporary = Kr_str.toFloat();
float Ti_temporary = Ti_str.toFloat();
float Td_temporary = Td_str.toFloat();

noInterrupts();
yref = yref_temporary;
Kr = Kr_temporary;
Ti = Ti_temporary;
Td = Td_temporary;
interrupts();

I think you have to make 'yref' volatile as well.

The Serial input is 115200 baud, that can be an interrupt every 87µs.
The Timer1 Myfunction runs every 50ms.
The Myfunction takes more than 600µs.

I did not measure the timing of 'Myfunction'. I calculated it for a rough number. 5 float divisions = 570µs. 11 float multiply = 117µs. 10 float substractions or additions = 10*7µs. Plus analogRead of 112µs. Plus a few more, that adds up to at least 600µs. It could be about 1ms.

Conclusion: Your 'Myfunction' is a real interrupt routine. When that is busy, the other interrupts have to wait. Since it takes more than 600µs, the Serial interrupts could be missed.
Perhaps a software timer with millis is accurate enough for the calculations.

Large update after the 'Update' label, since now the whole sketch was shown.
Source Link
Jot
  • 3.3k
  • 1
  • 14
  • 21
Loading
Source Link
Jot
  • 3.3k
  • 1
  • 14
  • 21
Loading