Hello everyone,
i want to run some parallel tasks on an Arduino Mega. I know the ATmega is a single Core chip, so real Parallel working processes are not possible. So i created a Timeslice sketch. Basically every element of an Array of Integer (called Counters) will be decreased by an Interrupt Service Routine. The ISR is Triggered by a Timer Interrupt every 2,5 ms. If the counter of the timeslice is less than 1 the determined piece of code will be executed and set the counter to a Value. Thats the Basic Concept of my Code.
So the Timeslice with the longest Duration is the limiting Factor. All other Timeslices have to run in a greater or equal Timedistance otherwise a new instruction should be executed during the Processor is working on the last Timeslice.
To adjust the Timing i measured the time for the Execution of each Timeslice (comment in the loop function) .
The Measurement works fine with all timeslices except the Timeslice for the LCD Display.
That is my fist Question: If i print out the Duration (end-begin) i got a negative value. i don't know what is the reason for that. The result was -33000. I took the Absolut Value of that and thought that the Duration is 33ms.
I can't explain that, maybe a reason could be that the I2C Library uses delay and delay Microseconds to controll the LC-Display. It would be nice if you would tell me some ideas what is causal for that.
The second Thing is that the LCD Timeslice is just a nice to have Feature and not important for my Project. The second longest timeslice is the Ethernet bus with 13 ms. Because of the long duration of the LC-Display i can't listen faster to the Ethernet Bus, what is very important for me.
Do you have some ideas to solve my Problems?
Thank you in advance!
i have shorted the code a little bit, so please do not wonder about missing declarations and suff like that.
#include <Arduino.h>
#include "Ethernet2.h"
#include "SPI.h"
#include "LiquidCrystal_I2C.h"
#include "Wire.h"
void TIM1_callback();
void printlcd();
//End of Auto generated function prototypes by Atmel Studio
byte mac[] = {0xA8, 0x61, 0x0A, 0xAE, 0x2F, 0xAB };
IPAddress ip(192, 168, 178, 177);
//IPAddress myDns(0, 0, 0, 0);
IPAddress gateway(10, 11, 141, 254);
IPAddress subnet(255, 255, 255, 0);
MCP3304 adc(49);
EthernetServer server(23);
SCPI_Parser Ultracap_Solution;
LiquidCrystal_I2C lcd(0x27,16,2);
Ultracap C1(39,8,3.519,1); //Constructor(bleeding Pin, Temp Pin, Factor Pos, Factor Neg)
Ultracap C2(41,9,7.829,3.519);
Ultracap C3(45,10,11,7.829);
Ultracap C4(43,11,15.705,11);
int counters[NO_COUNTERS];
bool Displaystatus = false;
int begin = 0;
int end = 0;
void setup() {
pinMode(17, INPUT);
pinMode(SS,OUTPUT);
Ethernet.begin(mac, ip);//, gateway, subnet);
server.begin();
lcd.begin();
Serial.begin(115200);
Timer1.initialize(1000000UL/INTS_PER_SECOND); // Timer Interrupt every 2500µs -> 400 Ints per Second...
Timer1.attachInterrupt(TIM1_callback);
for (byte i = 0; i < NO_COUNTERS; i++)
{
counters[i] = -1;
}
}
void loop() {
if (counters[Ethernet_Bus] < 1) {
counters[Ethernet_Bus] =15; // around 13.15ms
EthernetClient client = server.available();
if(client){
Ultracap_Solution.Execute(client);
}
}
if (counters[Volts] < 1) {
counters[Volts] = 10;// around 800µs
Akt_Vol();
}
if (counters[I2C_Display] < 1) {
begin = micros();
counters[I2C_Display] = 100; //around 33ms
printlcd();
end = micros();
Serial.println(end - begin);
}
if(counters[Cap_Temps]<100){
counters[Cap_Temps] = 80;// around 3 ms
Akt_Temp();
}
if(counters[Taster]<1){
counters[Taster] = 2; //knapp 1 ms
if((PINH & 0b00000001) == 0b00000001){
Displaystatus = !Displaystatus;
}
}
}
void TIM1_callback()
{
byte i = 0;
for (i = 0; i < NO_COUNTERS; i++)
{
if (counters[i] > -1)
counters[i]--;
}
}
void printlcd(){
if(Displaystatus==HIGH){
lcd.setCursor(0,0);
lcd.print("Vol1=");
lcd.print(C1.Get_Voltage(),2);
lcd.setCursor(0,16);
lcd.print("Vol2=");
lcd.print(C2.Get_Voltage(),2);
}
if(Displaystatus==LOW){
lcd.setCursor(0,0);
lcd.print("Temp1");
lcd.print(C1.Get_Temperature());
lcd.setCursor(0,16);
lcd.print("Temp2 ");
lcd.print(C2.Get_Temperature());
}
}
void Akt_Temp(){
C1.MeaTemp();
C2.MeaTemp();
C3.MeaTemp();
C4.MeaTemp();
}