I have written a code to run on my Arduino Leonardo, that is supposed to count the signals from a gas meter (mechanically, it's basically a switch, that closes and opens once per signal). So far, everything works just fine.
My problem is, that I also have three commands to send via serial communication from my PC.
The first one is supposed to run once when started and give the possibility to set a starting time:
Serial.println("Startzeit aendern? [Ja/Nein]");
while (!Serial.available());
while (Serial.available()) {
character = Serial.read();
content.concat(character);
}
if (content == "Ja") {
Serial.println("Versuchsdauer in Stunden eingeben");
while (!Serial.available());
while (Serial.available()) {
intervall = Serial.parseInt();
}
content = "default";
Serial.println("Zeit angepasst");
Serial.println("");
The next can be called at any time to clear the stored variables and end the program:
while (Serial.available()) { // überprüft, ob etwas an das Board gesendet wird
character = Serial.read(); // character ist jeweils ein Buchstabe
content.concat(character); // character wird an content angehängt
}
if (content == "clear") { // Vorgehen, falls "clear" gesendet wurde
Serial.println("...");
for (int i = 0; i <= 3; i++) { //
EEPROM.write(i, 0); // signalCounter wird wieder auf 0 gesetzt
Serial.print("Position ");
Serial.println(i);
delay(250);
}
Serial.println("Variablen zurueckgesetzt, Programm gestoppt");
while (1) {}
}
And finally, the third one can also be called when required and lets you also change the time in the serial output:
if (content == "Zeit") { // Vorgehen, falls "Zeit" gesendet wurde
Serial.println("Versuchsdauer in Stunden eingeben");
while (!Serial.available());
while (Serial.available()) {
intervall = Serial.parseInt();
}
content = "default";
Serial.flush();
Serial.println("Zeit angepasst");
}
Now the strange thing is, that every one of these works just fine, but only once per run. After one of them is used, the Arduino seems to not accept serial input anymore. Then I have to pull out the USB-cable and put it back in to use another command.
Does anyone know, what the problem might be?
Thank you in advance!
PS: As German is my mother language, all the comments are in German... If necessary, I can translate them for you.
PPS: Here is the whole code, if anyone needs more information:
#include <EEPROM.h>
void EEPROMWritelong(int address, long value) // die Funktion EEPROMWritelong() wird etabliert
{ //
byte four = (value & 0xFF); //dabei wird eine 4 Byte große long-Variable
byte three = ((value >> 8) & 0xFF); //in ihre einzelnen Bytes zerlegt (one ... four),
byte two = ((value >> 16) & 0xFF); //die dann auf separate Speicherplätze gelegt
byte one = ((value >> 24) & 0xFF); //werden.
//
EEPROM.write(address, four); //
EEPROM.write(address + 1, three); //
EEPROM.write(address + 2, two); //
EEPROM.write(address + 3, one); //
}
long EEPROMReadlong(long address) // Funktion EEPROMReadlong wird etabliert
{ //
long four = EEPROM.read(address); // zunächst werden die vier Bytes ausgelesen
long three = EEPROM.read(address + 1); //
long two = EEPROM.read(address + 2); //
long one = EEPROM.read(address + 3); //
// mithilfe der return-Funktion wird die ursprüngliche long-Variable wieder zusammengesetzt:
return ((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16) & 0xFFFFFF) + ((one << 24) & 0xFFFFFFFF);
}
const int gaszaehlerIn = 2; // definiert den Anschluss des Gaszählers
const float grundVolumen = 3.57; // Volumen pro Ausschlag; empirisch ermittelt
int currentState = 0; // aktueller Status (offen / geschlossen)
int lastState = 0; // vorheriger Status
long signalCounter = 0; // Anzahl an Signalen vom Gaszähler
long lastSignalCounter = 0; // Ausschläge bis zur jeweils aktuellen Messung
long starttime = 0;
long endtime = 0;
long intervall = 0; // Zeitangabe (1h - Intervalle)
String content = "";
char character;
void setup() {
pinMode(gaszaehlerIn, INPUT_PULLUP); // eingehende Signale werden registriert
Serial.begin(9600); // Baud für Verbindung wird festgelegt
while (!Serial) { // Board wartet auf eine serielle Verbindung
;
}
/*
Serial.println("Startzeit aendern? [Ja/Nein]");
while (!Serial.available());
while (Serial.available()) {
character = Serial.read();
content.concat(character);
}
if (content == "Ja") {
Serial.println("Versuchsdauer in Stunden eingeben");
while (!Serial.available());
while (Serial.available()) {
intervall = Serial.parseInt();
}
content = "default";
Serial.println("Zeit angepasst");
Serial.println("");
}
if (content == "Nein") {
;
}
*/
Serial.print("Zeit [h]"); //
Serial.print(" "); //
Serial.print("Volumen gesamt [ml]"); //
Serial.print(" "); //
Serial.print("aktueller Volumenstrom [ml/min]"); //
Serial.print(" "); //
Serial.println("Ausschlaege"); // Benennung der Tabellenspalten
signalCounter = EEPROMReadlong(0); // signalCounter vom letzten Mal wird geladen
lastSignalCounter = signalCounter;
Serial.print(intervall); // Zeit der Messung wird eingetragen
Serial.print(" ");
Serial.print(signalCounter * grundVolumen); // Berechnung des Gesamtvolumens
Serial.print(" ");
Serial.print((signalCounter - lastSignalCounter) * grundVolumen / 60); // Berechnung des aktuellen Volumenstroms
Serial.print(" ");
Serial.println(signalCounter); // Menge der Ausschläge wird eingetragen
intervall = intervall + 4; // die Zeitangabe wird aktualisiert
}
void loop() {
do {
starttime = millis();
currentState = digitalRead(gaszaehlerIn);
if (currentState != lastState) { // eine Änderung des Signals vom Gaszähler initiiert den nächsten Schritt
if (currentState == LOW) { // ist das Signal LOW? (=liegt eine Spannung an?)
signalCounter++; // ist dem so, wird der Counter um 1 erhöht
delay (250); // 250ms Wartezeit, damit ein Signal nicht als mehrere gezählt wird
}
else { // für den Fall, dass das Signal LOW ist:
;
}
}
lastState = currentState; // lastState und currentState werden wieder gleich gesetzt
while (Serial.available()) { // überprüft, ob etwas an das Board gesendet wird
character = Serial.read(); // character ist jeweils ein Buchstabe
content.concat(character); // character wird an content angehängt
}
if (content == "clear") { // Vorgehen, falls "clear" gesendet wurde
Serial.println("...");
for (int i = 0; i <= 3; i++) { //
EEPROM.write(i, 0); // signalCounter wird wieder auf 0 gesetzt
Serial.print("Position ");
Serial.println(i);
delay(250);
}
Serial.println("Variablen zurueckgesetzt, Programm gestoppt");
while (1) {}
}
if (content == "Zeit") { // Vorgehen, falls "Zeit" gesendet wurde
Serial.println("Versuchsdauer in Stunden eingeben");
while (!Serial.available());
while (Serial.available()) {
intervall = Serial.parseInt();
}
content = "default";
Serial.flush();
Serial.println("Zeit angepasst");
}
} while ((starttime - endtime) < 10000); // für 4h wird der Loop wiederholt
endtime = starttime; // End- und Startzeit werden wieder gleichgesetzt
Serial.print(intervall); // Zeit der Messung wird eingetragen
Serial.print(" ");
Serial.print(signalCounter * grundVolumen); // Berechnung des Gesamtvolumens
Serial.print(" ");
Serial.print((signalCounter - lastSignalCounter) * grundVolumen / 240); // Berechnung des aktuellen Volumenstroms
Serial.print(" ");
Serial.println(signalCounter); // Menge der Ausschläge wird eingetragen
intervall = intervall + 4; // die Zeitangabe wird aktualisiert
long address = 0;
EEPROMWritelong(address, signalCounter); // falls das Arduino zwischenzeitlich vom PC getrennt wird, wird der signalCounter gespeichert
address += 4;
lastSignalCounter = signalCounter;
}