Puh, ehrlich, das überfordert mich in der Tat jetzt etwas. Du meinst du millis am SerialMonitor ausgeben?
Dann solltest Du Dich etwas mehr mit den Grundlagen beschäftigen. Sowas brauchst Du immer wieder.
Serial.print("Millis: "); Serial.print(millis()); Serial.print("LED_timestore: "); Serial.println(LED_timestore);
Du hast weiter oben nach einem Beispiel zum Einlesen von Integer-Werten in ein Array gefragt.
Hier ein Beispiel mit weniger Eingaben:
// intRead
// Beispieleingabe 10 Werte (mit NL abschließen) 1|2|33|44|555|66|77|88|0|1
const uint8_t feldAnzahl = 10;
int werte[feldAnzahl];
uint8_t feldIdx, pufferIdx;
char puffer[10];
void setup() {
Serial.begin(115200);
Serial.println("Start");
}
// return true, wenn ganze Zeile eingelesen, sonst false
boolean einlesen() {
char c;
if (Serial.available()) {
c = Serial.read();
if (c == '|' || c == '\n') {
puffer[pufferIdx] = '\0'; // Abschließen der Zeichenkette
if (feldIdx < feldAnzahl) {
werte[feldIdx++] = atoi(puffer);
pufferIdx = 0;
if (c == '\n') return true; // Zeile fertig
}
}
else if (c >= '0' && c <= '9') puffer[pufferIdx++] = c; // Nur Ziffern
}
return false;
}
void anzeigen() {
for (uint8_t i = 0; i < feldAnzahl; i++) {
Serial.print(werte[i]); Serial.print(" ");
}
Serial.println("");
}
void loop() {
if (einlesen()) anzeigen();
}
photojo:
Das mit "struct" kenne/kannte ich noch nicht. Daher würde ich es bevorzugen, alle gesendenten Werte in ein Array zu übertragen. Mit dem Array bzw. dessen Werte schließlich meine gewünschten Operationen mit eigenen Funktionen auszuführen, ich denke, das kriege ich irgendwie hin, vielleicht auch nochmal mit kleineren Hilfestellungen im Forum.
Mein Hauptproblem ist im Moment aber einfach das, dass ich die 49 Werte ordentlich übertragen und gespeichert bekomme, damit ich mit ihnen arbeiten kann.
Wenn da mal einen "Mustercode" eines erfahreren Programmierers sehen könnte, wäre mir sehr geholfen. Wo und wie ich dann meinen eigentlichen Prozeduren implementiere probiere ich halt dann.
Ich würde ja mal sagen:
Wenn deinen Daten eine (natürliche) Struktur inne wohnt, dann sollte man das auch im Programmtext so wieder finden.
Der Umgang mit c/C++ Strukturen ist keine Geheimwissenschaft. Und das erlernen trägt vielfältig Früchte.
Das eigentliche Zerlegen mit strtok() und atoi() ist dagegen eher einfach.
Vielen Dank für deine freundlichen Worte, aber wenn so manches rudimentäre nicht klappen will, da werde ich mich sicher auch nicht mit Neuem beschäftigen.
Ich komm einfach nicht weiter und habe quasi nochmal neu angefangen:
#define NUMBER_OF_FIELDS 22
int values[NUMBER_OF_FIELDS];
byte fieldIndex;
int ventil_1 = 2;
int openings[] = {0, 0, 0};
int cam;
unsigned long LED_timestore;
int LedStatus = LOW;
//
int data[NUMBER_OF_FIELDS];
void setup()
{
Serial.begin(9600);
//Serial.println("Anfang");
pinMode (2, OUTPUT);
}
void loop()
{
if ( Serial.available() > 0)
{
//Serial.println("verbunden");
char ch = Serial.read();
if (ch >= '0' && ch <= '9') // ASCII-Zeichen zwischen 0 und 9?
{
if (fieldIndex < NUMBER_OF_FIELDS) {
values[fieldIndex] = (values[fieldIndex] * 10) + (ch - '0');
}
}
else if (ch == '|')
{
data[fieldIndex] = values[fieldIndex];
fieldIndex++;
}
else if (ch == '\n')
{
for (int z = 0; z < 3; z++)
{
openings[z] = 0;
}
loops = 0;
if (values[9] == 1) {
digitalWrite (2, HIGH); // Ventil_1 auf zum Durchspülen
} else if (values[9] == 0) {
}
for (int i = 0; i < NUMBER_OF_FIELDS; i++)
{
values[i] = 0; // loeschen
}
fieldIndex = 0; // für Neustart
}
}
//Öffnung 1
if (openings[0] == 0 ) {
if (LedStatus == LOW && openings[0] == 0 ) {
if (millis() - LED_timestore > data[1]) { // zeit für aus
digitalWrite(ventil_1, HIGH);
LED_timestore = millis();
LedStatus = HIGH;
}
} else {
if (millis() - LED_timestore > data[2]) { //zeit für an
digitalWrite(ventil_1, LOW);
LedStatus = LOW;
openings[0] = 1;
}
}
}
//Öffnung 1 ENDE
}
Ziel: NACH dem Senden von Daten soll die LED nach data[1] angehen und nach data[2] ausgehen.
Dann setze ich openings[0] auf eins, damit die Sache nur einmal läuft.
Kann mir bitte jemand erfolgende erklären:
data[1] ist auf 8000
data[2] ist auf 1000
Warum geht die LED mal nach 5 Sekunden an, mal sofort, mal nach 2 Sekunden? Brennen tut sie immer exakt 1 Sekunde?
Ich hatte Dir eine Beispiellösung zum Einlesen gegeben.
Wenn Du der Meinung bist, am Ende des Einlesens (beim \n alles löschen zu müssen, dann wird das wohl so sein müssen.
Außerdem hatte ich Dir empfohlen, an die kritischen Stellen serielle Ausgaben einzubauen.
Alle diese Vorschläge ignorierst Du beharrlich.
Wenn Du statt dessen lieber mit Deinen Ideen rumspielen willst, dann mach das.
Ich bin dann raus.
Gruß Tommy
Ich entschuldige mich. Ich habe dein Beispiel einfach übersehen. Sorry. Ich probiere es gleich mal.
Herzlichen Dank! Es klappt und ich kann es auch halbwegs gut nachvollziehen.
Aber bitte beantworte mir noch eine Frage: wenn ich mehrfach hintereinander unterschiedliche Werte sende, bleiben immer nur die zuerst gesendeten sichtbar? Das verstehe ich nicht.
DANKE!
Dass Du mehrfach eingeben willst, hast Du nicht geschrieben.
Probier mal das:
// intRead
// Beispieleingabe 10 Werte (mit NL abschließen) 1|2|33|44|555|66|77|88|0|1
const uint8_t feldAnzahl = 10;
int werte[feldAnzahl];
uint8_t feldIdx, pufferIdx;
char puffer[10];
boolean gelesen = false;
void setup() {
Serial.begin(115200);
Serial.println("Start");
}
void loeschen() {
for (uint8_t i = 0; i < feldAnzahl; i++) {
werte[i] = 0;
}
feldIdx = 0;
gelesen = false;
}
// return true, wenn ganze Zeile eingelesen, sonst false
boolean einlesen() {
char c;
if (Serial.available()) {
if (gelesen) loeschen();
c = Serial.read();
if (c == '|' || c == '\n') {
puffer[pufferIdx] = '\0'; // Abschließen der Zeichenkette
if (feldIdx < feldAnzahl) {
werte[feldIdx++] = atoi(puffer);
pufferIdx = 0;
if (c == '\n') {
gelesen = true;
return true; // Zeile fertig
}
}
}
else if (c >= '0' && c <= '9') puffer[pufferIdx++] = c; // Nur Ziffern
}
return false;
}
void anzeigen() {
for (uint8_t i = 0; i < feldAnzahl; i++) {
Serial.print(werte[i]); Serial.print(" ");
}
Serial.println("");
}
void loop() {
if (einlesen()) anzeigen();
}
Neu hinzu gekommen ist die Variable gelesen.
Gruß Tommy
VIELEN HERZLICHEN DANK!
Ich werde mir jetzt eine Funktion für ein Ventil bzw. LED basteln. Mal schauen!
Aber nochmals: vielen Dank!
Du hast mir sehr geholfen. Ich möchte deine Hilfsbereitschaft auch nicht übertrapazieren, aber ich stelle nochmal eine Frage: Ich habe in loop zunächst ohne Funktion eine Routine eingebaut. Die LED soll nach einer Vorlaufzeit wert[0] für wert[1] ms leuchten. Das ganze soll nur einmal geschehen, dafür die Variable abgearbeitet. Kommen neue Werte rein, soll es eben wieder abgearbeite werden.
Die Vorlaufzeit wird leider nicht "beachtet", warum?
// intRead
// Beispieleingabe 10 Werte (mit NL abschließen) 1|2|33|44|555|66|77|88|0|1
const uint8_t feldAnzahl = 10;
int werte[feldAnzahl];
uint8_t feldIdx, pufferIdx;
char puffer[10];
boolean gelesen = false;
boolean abgearbeitet = false;
//
int ventil_1 = 2;
unsigned long LED_timestore;
int LedStatus = LOW;
void setup() {
Serial.begin(115200);
Serial.println("Start");
pinMode (2, OUTPUT);
}
void loeschen() {
for (uint8_t i = 0; i < feldAnzahl; i++) {
werte[i] = 0;
}
feldIdx = 0;
gelesen = false;
}
// return true, wenn ganze Zeile eingelesen, sonst false
boolean einlesen() {
char c;
if (Serial.available()) {
if (gelesen) loeschen();
c = Serial.read();
if (c == '|' || c == '\n') {
puffer[pufferIdx] = '\0'; // Abschließen der Zeichenkette
if (feldIdx < feldAnzahl) {
werte[feldIdx++] = atoi(puffer);
pufferIdx = 0;
if (c == '\n') {
gelesen = true;
abgearbeitet = false;
return true; // Zeile fertig
}
}
}
else if (c >= '0' && c <= '9') puffer[pufferIdx++] = c; // Nur Ziffern
}
return false;
}
void anzeigen() {
for (uint8_t i = 0; i < feldAnzahl; i++) {
Serial.print(werte[i]); Serial.print(" ");
}
Serial.println("");
}
void loop() {
if (einlesen()) anzeigen();
if (LedStatus == LOW && abgearbeitet == false ) {
if (millis() - LED_timestore > werte[0]) { // zeit für aus
digitalWrite(ventil_1, HIGH);
LED_timestore = millis();
LedStatus = HIGH;
}
} else {
if (millis() - LED_timestore > werte[1]) { //zeit für an
digitalWrite(ventil_1, LOW);
LedStatus = LOW;
abgearbeitet = true;
}
}
}
Generelles Ziel wäre übrigens:
warte wert[0]
öffne für wert[1]
warte wert[2]
öffne für wert[3]
warte wert[4]
öffne für wert[5]
Vielen Dank. Klingt abgedroschen, ist aber sehr aufrichtig gemeint!
Ich hatte Dir auch gesagt, gib Dir die Werte aus, wenn etwas nicht so läuft, wie es soll, damit Du siehst, was Dein Programm macht.
Davon sehe ich aber nichts.
Gruß Tommy
Selbstverständlich lasse ich mir die entsprechenden Parameter zur Kontrolle ausgeben, habe es der Übersichtlichkeit halber hier nicht gepostet. Sorry.
Dann müsstest Du ja auch sehen, warum es nicht das tut, was es soll.
Zeige mal die Ausgabe der eingelesenen Werte.
Gruß Tommy
Edit: Ich will Dich nicht trietzen, sondern an die Fehlersuche heran bringen. Ich kann mir vorstellen, wo das Problem liegt aber wenn Du an der Fehlersuche beteiligt bist, verstehst Du eher die Abläufe.
Klar, ich will möglichst viel lernen bei der ganzen Sache. Bin heute nicht mehr am Rechner, schicke morgen mal meinen aktuellen Code und die Ausgabe.
Gruß
Jo
Alles klar. Schönen Abend noch.
Gruß Tommy
Guten Morgen, Tommy.
Habe mich gleich vor der Arbeit hingesetzt. Ich poste hier meinen aktuellen CODE mit zwei Ausgabezeilen, hoffentlich an der richtigen Stelle!?
Ich bitte dich jedoch, dir die Ausgabe bei deinem Arduino anzusehen, falls möglich, den bei mir "rattern" die Zeilen ja nur so durch. ich danke im Voraus.
// intRead
// Beispieleingabe 10 Werte (mit NL abschließen) 5000|1000|33|44|555|66|77|88|0|1
const uint8_t feldAnzahl = 10;
int werte[feldAnzahl];
uint8_t feldIdx, pufferIdx;
char puffer[10];
boolean gelesen = false;
boolean abgearbeitet = false;
//
int ventil_1 = 2;
unsigned long LED_timestore;
int LedStatus = LOW;
void setup() {
Serial.begin(115200);
Serial.println("Start");
pinMode (2, OUTPUT);
}
void loeschen() {
for (uint8_t i = 0; i < feldAnzahl; i++) {
werte[i] = 0;
}
feldIdx = 0;
gelesen = false;
}
// return true, wenn ganze Zeile eingelesen, sonst false
boolean einlesen() {
char c;
if (Serial.available()) {
if (gelesen) loeschen();
c = Serial.read();
if (c == '|' || c == '\n') {
puffer[pufferIdx] = '\0'; // Abschließen der Zeichenkette
if (feldIdx < feldAnzahl) {
werte[feldIdx++] = atoi(puffer);
pufferIdx = 0;
if (c == '\n') {
gelesen = true;
abgearbeitet = false;
return true; // Zeile fertig
}
}
}
else if (c >= '0' && c <= '9') puffer[pufferIdx++] = c; // Nur Ziffern
}
return false;
}
void anzeigen() {
for (uint8_t i = 0; i < feldAnzahl; i++) {
Serial.print(werte[i]); Serial.print(" ");
}
Serial.println("");
}
void loop() {
if (einlesen()) anzeigen();
//LED=Ventil ein/ausschalten START
if (LedStatus == LOW && abgearbeitet != true ) {
//LED_timestore = millis();
if (millis() - LED_timestore > werte[0]) { // zeit für aus
digitalWrite(ventil_1, HIGH);
LED_timestore = millis();
LedStatus = HIGH;
Serial.print("Millis: "); Serial.print(millis()); Serial.print(" LED_timestore: "); Serial.println(LED_timestore); Serial.print("Abschnitt HIGH"); Serial.println(abgearbeitet);
}
} else {
if (millis() - LED_timestore > werte[1]) { //zeit für an
digitalWrite(ventil_1, LOW);
LedStatus = LOW;
abgearbeitet = true;
Serial.print("Millis: "); Serial.print(millis()); Serial.print(" LED_timestore: "); Serial.println(LED_timestore); Serial.print("Abschnitt LOW "); Serial.println(abgearbeitet);
}
}
//LED=Ventil ein/ausschalten ENDE
}
Schon das Durchrattern zeigt, dass da was faul ist.
Und wenn Du Dir das anschaust (Autoscroll ausmachen) Dann solltest Du 3 Singe sehen:
-
Es kommt eine Zeile mit Millis: 1 LED_timestore: 1 HIGH
-
Es kommen viele Zeilen mit: Millis: ..... LOW
-
Du hast noch überhaupt keine Eingaben gemacht
-
bedeutet alle Intervalle sind 0 also läuft es los (1).
-
Es schaltet sofort wieder aus, wiel auch da 0 drin steht.
Wir dürfen das Ganze also erst starten, wenn die Daten eingelesen sind. Wir brauchen für jedes Ventil eine Reihe Variable. Deshalb hatte ich die Struktur vorgeschlagen, damit das übersichtlicher bleibt.
So funktioniert es:
// intRead
// Beispieleingabe 10 Werte (mit NL abschließen) 5000|1000|33|44|555|66|77|88|0|1
const uint8_t feldAnzahl = 10;
int werte[feldAnzahl];
uint8_t feldIdx, pufferIdx;
char puffer[10];
boolean gelesen = false;
boolean abgearbeitet = true;
//
int ventil_1 = 2;
unsigned long LED_timestore;
int LedStatus = LOW;
void setup() {
Serial.begin(115200);
Serial.println("Start");
pinMode (2, OUTPUT);
}
void loeschen() {
for (uint8_t i = 0; i < feldAnzahl; i++) {
werte[i] = 0;
}
feldIdx = 0;
gelesen = false;
}
// return true, wenn ganze Zeile eingelesen, sonst false
boolean einlesen() {
char c;
if (Serial.available()) {
if (gelesen) loeschen();
c = Serial.read();
if (c == '|' || c == '\n') {
puffer[pufferIdx] = '\0'; // Abschließen der Zeichenkette
if (feldIdx < feldAnzahl) {
werte[feldIdx++] = atoi(puffer);
pufferIdx = 0;
if (c == '\n') {
gelesen = true;
abgearbeitet = false;
LED_timestore = millis(); // jetzt erst geht die Zeit los
Serial.print(" LED_timestore gesetzt auf: "); Serial.println(LED_timestore);
return true; // Zeile fertig
}
}
}
else if (c >= '0' && c <= '9') puffer[pufferIdx++] = c; // Nur Ziffern
}
return false;
}
void anzeigen() {
for (uint8_t i = 0; i < feldAnzahl; i++) {
Serial.print(werte[i]); Serial.print(" ");
}
Serial.println("");
}
void loop() {
if (einlesen()) anzeigen();
//LED=Ventil ein/ausschalten START
if (abgearbeitet != true ) {
if (LedStatus == LOW && millis() - LED_timestore >= werte[0]) { // zeit für aus
Serial.print("Millis: "); Serial.print(millis()); Serial.print(" LED_timestore: "); Serial.println(LED_timestore); Serial.print("Abschnitt HIGH"); Serial.println(abgearbeitet);
digitalWrite(ventil_1, HIGH);
LED_timestore = millis();
Serial.print(" LED_timestore gesetzt auf: "); Serial.println(LED_timestore);
LedStatus = HIGH;
}
if (LedStatus == HIGH && millis() - LED_timestore >= werte[1]) { //zeit für an
Serial.print("Millis: "); Serial.print(millis()); Serial.print(" LED_timestore: "); Serial.println(LED_timestore); Serial.print("Abschnitt LOW "); Serial.println(abgearbeitet);
digitalWrite(ventil_1, LOW);
LedStatus = LOW;
abgearbeitet = true;
}
}
//LED=Ventil ein/ausschalten ENDE
}
Gruß Tommy
Wow! Vielen Dank!!! Es arbeitet perfekt! Nach 10 Tagen bin ich endlich soweit und happy!
Bei deinem CODE steht
...
if (abgearbeitet != true ) {
if (LedStatus == LOW && millis() - LED_timestore >= werte[0]) {
...
bei meinem das
...
if (LedStatus == LOW && abgearbeitet != true ) {
if (millis() - LED_timestore > werte[0]) {
...
Ich dachte einfach, das sei das äquivalent.
Der Teil ist nicht das Problem, sondern Dein else dazu.
LedStatus wird noch mehr Zustände annehmen müssen, wenn Du die weiteren Pausen- und Laufzeiten zu diesem Ventil hinzufügen mußt.
Lass die anderen Ventile erst mal weg und mache nur das eine fertig. Mit den 1-Laufflags und den weiteren Zeiten und dem Spülen.
Ich vermute, wenn Spülen gesetzt ist, werden die anderen Werte 0 sein?
Gruß Tommy