if(millis()/1000>crontimer+3){//alle 3s Daten senden via RS232
16
crontimer=millis()/1000;
17
Serial.println(pulse_total);
18
}
19
}
20
21
voidonPulse(){
22
if((millis()-alteZeit)>21){// innerhalb der Entprellzeit 21ms nichts machen
23
alteZeit=millis();// letzte Schaltzeit merken
24
pulse_total++;
25
}
26
}
Solange ich mit einem Programm (z.B. Minicom) den USB Port des Nano auslese, sehe ich wie er hoch zählt:
200000
200003
200006
100010....
Problem: Sobald ich Minicom schließe und anschließend wieder öffne fängt er wieder bei 200000 an.
Meine erste Vermutung war, dass es sich um ein Problem mit der Stromversorgung handelt aber auch wenn man ein Netzteil an +5V oder Vin anschließt bleibt das Problem bestehen.
Was kann ich sonst noch testen? - Mir gehen langsam die Ideen aus.
VG Andi
Auf der Platine ist ein Schaltkreis, der den Controller resettet wenn eine Terminal-Verbindung aufgebaut wird.
Man kann es Verhindern, wenn man in seinem Terminal-Programm die Hardware-Flusskontrolle deaktiviert. Oder man Durchtrennt die Leiterban, DTR-Ausgang des UART-Controllers.
Den Reset zu unterbinden ist ja nichtmal die Hälfte der Miete.
Kurze Stromzappler? Irgendwann mal kurz ausmachen zum Putzen? Oder oder oder?
Irgendein Töffel vergisst vor dem Anstecken das Handshaking abzuschalten, benutzt einen doofen Adapter oder Treiber, bingo.
Jedesmal hoppelt das Ding auf Null zurück, das ist ja Quatsch und völlig instabil.
Was es da braucht ist ein nichtflüchtiger Speicher, in den zumindest ab und an mal der aktuelle Stand gesichert wird, so das man z.B. nur 5 Minuten verliert oder so.
Da muss man aber aufpassen, denn die haben teilweise arg begrenzte Schreibzyklen...
Am besten geht's mit einem FRAM, das sollte selbst bei Sekundenzyklen Jahrzehnte schaffen, bleibt nur noch das Risiko, das man bei so einem Reset genau den Schreibzyklus unterbricht und der Speicher korrupt wird.
Was es da braucht ist ein nichtflüchtiger Speicher, in den zumindest ab
und an mal der aktuelle Stand gesichert wird, so das man z.B. nur 5
Minuten verliert oder so.
Da muss man aber aufpassen, denn die haben teilweise arg begrenzte
Schreibzyklen...
Man müsste sich da was ausdenken, dass man den nichtflüchtigen Speicher auf viele Speicherzellen verteilen kann. "Wear Leveling" nennt sich das auf Fach-Chinesisch - und selbst Tante Google kann was dazu sagen.
Nachdem ihr mich darauf hingewiesen habt, sah ich auch das die Reset-LED immer aufblinkt wenn man minicom starte oder beendet.
Ich habe jetzt den Kondensator an DTR ausgelötet. So funktioniert alles wie gewollt.
Zum Thema Datensicherheit:
Ich hatte auch erst vor in gewissen Intervallen die Werte in den EEPROM zu schreiben. Da ich die Daten aber sowieso regelmäßig per USB auslese und speichere habe ich das wieder verworfen.
Da ich die Daten aber sowieso regelmäßig per USB auslese
und speichere habe ich das wieder verworfen.
Dann solltest du die Übertragung einfach auf die Anzahl der Pulse seit dem letzten Auslesen ausführen und den Stand am Auslesegerät festhalten.
Da kannst du dann auch bequemer den aktuellen Stand nachhalten, falls dein Adapter mal was vergessen hat.
Überleg dir, was passiert sobald millis() seinen 32-bit-Rollover hat.
Es passiert viel öfter Seltsames. Nämlich schon, wenn "geschickt" zwischen if(millis()/1000 > crontimer + 3){ und crontimer = millis()/1000;
der millis-Zähler einen der allsekündlichen Tausender-Überläufe hat. Dann wird nämlich eine "Schaltsekunde" eingelegt, wenn z.B. zum Zeitpunkt der if-Abfrage millis() noch 12999 hatte, beim Berechnen des neuen crontimer Werts aber schon auf 13000 weitergezählt hat.
Schöner:
if ((millis() - crontimer)>3000) {
crontimer=millis();
Und noch viel viel schöner ist es, wenn man am Anfang der Mainloop ein einziges Mal den millis()-Zeitstempel abholt und den Rest im Zyklus mit derselben Zeit rechnet:
1
unsignedlongjetzt,crontimer=0,t5s=0;
2
3
voidloop(){
4
jetzt=millis();// einmalig Zeitstempel für diesen Schleifendurchlauf abholen
5
6
if(jetzt-crontimer>3000){// alle 3s ...
7
crontimer=jetzt;
8
Serial.println(pulse_total);
9
}
10
11
if(jetzt-t5s>5000){// alle 5 s
12
t5s=jetzt;
13
:
14
}
15
}
Und so richtig schön wäre es dann, wenn man am Anfang der Schleife die Eingänge ebenfalls auf ein Prozessabbild einlesen und alle berechneten Änderungen erst am Schluss der Schleife auf die Ausgänge schreiben würde. Dann hat man nämlich die vielmillionenfach erprobte Vorgehensweise einer SPS. Da kann zwar die Zykluszeit der SPS insgesamt zu langsam sein, es gibt aber kein seltsames Timingverhalten wegen einer zum Programmablauf hinzugefügten Funktion.
Eine eigene Frage?
Dieser Thread ist über 3 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.