Vielen Dank für die Rückmeldungen!
michael_x:
Es geht ganz einfach:
const unsigned int PERIODE= 10000;
unsigned long last = -5000L; // das geht schon
void loop() {
unsigned long now = millis();
if ( now - last > PERIODE) {
last += PERIODE;
// Hier der 10-Sekundentakt, zuerst 5 sec nach Start
}
}
Die ersten Differenzen ergeben:
0 - (-5000) = 5000
...
1000 - (-5000) = 6000
5000 - (-5000) = 10000 --> Periode erreicht
6000 - (5000) = 1000
Dass last als unsigned deklariert ist, macht für die eigentliche Berechnung nichts aus,
würde nur in einem println nicht als -5000 sondern als 4294962296 angezeigt. (Was nur blöde vorher auszurechnen und so einzutippen wäre)
Das ist tatsächlich "ganz einfach" und scheint gut zu funktionieren, allerdings nur, wenn OFFSET <(=?) Periode ist, was bei mir auch anders sein kann.
Mir scheint die vermischte Variante von jurs und michael_x mit dem long dt und long Periode sowie -Werten gut für alle erdenklichen Fälle zu funktionieren. Dabei scheint "jetzt" unsigned long bleiben zu dürfen (sonst gibt es doch bei großen Zahlen Probleme mit der Zuweisung unsigned zu signed!?)
* /*
* Offset für Task:
* Vor Start wird last mit Offset initialisiert:
* Soll die Task x [ms] nach Start zum ersten Mal erfolgen: last = x - Periode; [ms]
*
* Bsp: Periode = 1000; [ms]
* x[ms] last[ms]
* ------------------------
* 0 -1000* *(last darf NICHT last < (-Periode) sein!
* 900 -100
* 1000 0
* 1100 100
* 5000 4000
* ... ...
*
* unsigned long jetzt;
* unsigned long last;
* long periode;
* long dt; oder ohne extra variable dt: if( (long)(millis()-last) >= periode )
*/
*
Sehr schön, so wollte ich es gerne haben! Vielen Dank! 
Hier noch mein Test-Code (aber nicht hauhen, habe mir da ein sicherlich ganz böses Macro gebastlet um Tipparbeit zu sparen und for Fun!)
/*
* 150820 V003 Test_Offset_signed_V003.ino
*
* Test Sketsch für Task-Scheduller Berechnungen mit Start-Offste
*
* Offset für Task:
* Vor Start wird last mit Offset initialisiert:
* Soll die Task x [ms] nach Start zum ersten Mal erfolgen: last = x - Periode; [ms]
*
* Bsp: Periode = 1000; [ms]
* x[ms] last[ms]
* ------------------------
* 0 -1000* *(last darf NICHT last < (-Periode) sein!
* 900 -100
* 1000 0
* 1100 100
* 5000 4000
* ... ...
*
* unsigned long jetzt;
* unsigned long last;
* long periode;
* long dt; oder ohne extra variable dt: if( (long)(millis()-last) >= periode )
*/
//### Setable Defines ################################################################
#define DEBUG_TASK 2 // Set Task Debug Leve /Info (0~2)
#define USE_MICROS 0 // use micros() instead of millis() [NOT INSTALLED]
//************************************************************************************
//### Edit Task Array ###############################################################
//const int CNT = 3; // Task Count
#define CNT (sizeof(last)/sizeof(last[0])) // Task/Array Count
unsigned long last[] = {-500, 0, 0 }; // last exec. / Start Offset
int periode[]= {1000, 1000, 1000 }; // Periode
bool state[] = {0, 0, 0 }; // inner LED State
const byte pin[] = {13, 12, 11 }; // LED Pin
//************************************************************************************
//### Global Var. for Task exec. #####################################################
unsigned long jetzt = 0; // akt. Zeitmerker
//long dt = 0; // Differenzzeit (signed!)
//************************************************************************************
//### Define TASK(x) Exec. Test and Service Macro ####################################
/*
#define TASK(x) if((long)(millis()-last[x]) >= periode[x]){\
jetzt = millis();\
SerialDebug(x); \
last[x] += periode[x]; \
byte _tID = x;
*/
#define TASK(x) jetzt = millis(); \ // Ok geht! ohne long dt
if((long)(jetzt-last[x]) >= periode[x]){\
SerialDebug(x); \
last[x] += periode[x]; \
byte _tID = x;
/*
#define TASK(x) jetzt = millis(); \
dt = (jetzt - last[x]); \
if(dt >= periode[x]){ \
SerialDebug(x); \
if(dt > (periode[x]*2)){ \ // ändern des last gewollt??
last[x] = jetzt; \
} \
else{ \
last[x] += periode[x]; \
} \
byte _tID = x;
*/
//************************************************************************************
//### Debug Leve für Task Exec. Info ##################################################
#if (DEBUG_TASK == 1) // Get Task exec. Info
void SerialDebug(byte x){
Serial.println();
Serial.print(jetzt);
Serial.print(F("\tTask: "));
Serial.print(x);
}
#elif (DEBUG_TASK == 2) // +additional Task Parameter
void SerialDebug(byte x){
Serial.println();
Serial.print(jetzt);
Serial.print(F("\tTask: "));
Serial.print(x);
Serial.print(F("\tLast: "));
Serial.print(last[x]);
Serial.print(F("\tPeriod: "));
Serial.print(periode[x]);
}
#else
void SerialDebug(byte x){
}
#endif
//************************************************************************************
//####################################################################################
void setup() {
// put your setup code here, to run once:
for (byte y=0;y<CNT;y++){ // Init LED Pins
pinMode(pin[y], OUTPUT);
}
Serial.begin(230400); // Start Serial
Serial.println(F("\n\nStarting...\n\n" __FILE__ "\n" __DATE__ "\n" __TIME__ "\n"));
}//void setup()
//************************************************************************************
//####################################################################################
//### main loop() ####################################################################
void loop() {
// put your main code here, to run repeatedly:
//-----------------------------------------------
TASK(0) // Task(_tID) (NO "{" after "Task()" !)
if(state[_tID]){ // LED is on
digitalWrite(pin[_tID],LOW);
}
else{ // LED is off
digitalWrite(pin[_tID],HIGH);
}
state[_tID] = !state[_tID];
}//Task[0] --------------------------------------
//-----------------------------------------------
TASK(1) // Task(_tID) (NO "{" after "Task()" !)
if(state[_tID]){ // LED is on
digitalWrite(pin[_tID],LOW);
}
else{ // LED is off
digitalWrite(pin[_tID],HIGH);
}
state[_tID] = !state[_tID];
}//Task[1] --------------------------------------
}//void loop()************************************************************************
//************************************************************************************