ich habe eine Frage zu o.g. Thema und hoffe, hier Hilfe zu bekommen
Folgendes Projekt läuft bei mir:
Ich baue gerade ein Messsystem aus 3 digitalen Messuhren auf. Diese habe ich geöffnet, die DRO Lötstellen angezapft und über einen vorgefertigten Code ( Arduino reads digital caliper - martin's useless and useful creations ) lese ich Messwerte aus. Das klappt alles wunderbar, auch das Level-Shifting von 1,5 V auf 5 V mit 2 NPN-transistoren (BC 547) klappt ohne Probleme.
Ich würde nun gerne zu Beginn einfach abfragen, ob die Messuhren überhaupt angeschlossen bzw. eingeschaltet sind.
Die Uhren senden in regelmäßigen Abständen ein 24-bit Signal.
Im Prinzip müsste ich zu Beginn des Programms also einfach abfragen, ob da am Anfang am Digital Pin ein Clocksignal eintrifft, stehe aber irgendwie auf dem Schlauch, wie ich das programmiertechnisch sauber hinbekomme.
Kann mich da jemand in die richtige Richtung lenken?
Ich würde nun gerne zu Beginn einfach abfragen, ob die Messuhren überhaupt angeschlossen bzw. eingeschaltet sind.
link:
Between each series of 24 bits there is a longer period during which CLK remains HIGH
Wenn du den Arduino-Pin als INPUT_PULLUP definierst, ist er HIGH wenn nichts angeschlossen ist und LOW, wenn dein Messschieber zwar dran ist, aber gerade Ruhe hat. Da ist es sogar egal, ob ohne Messschieber auch kein Transistor angeschlossen ist.
Den Widerstand nach 5V vom Kollektor brauchst du übrigens nichtmal bei INPUT_PULLUP. Da kannst du den Kollektor direkt an den Arduino - Pin anschliessen.
Danke schon mal für die Antwort, habe bis jetzt nur 1,2 Kleinigkeiten mit dem Arduino gemacht und wusste gar nicht, dass er interne Pullup-Widerstände hat.
Allerdings hab ich mir die Level-Shift-Geschichte schon zusammengelötet auf ne Platine, also nutze ich das nun auch so. Für das nächste Projekt weiß ich Bescheid
Ich weiß nun aber noch nicht, wie ich mein Vorhaben im Code umsetzen kann.
Ich bräuchte irgendeine Prozedur, die vor dem Hauptcode halt sowas abfragt wie:
"Wenn 1 Sekunde lang kein Wechsel LOW/HIGH am Input Pin festgestellt wurde gib einen Fehler oder eine Meldung aus"
Die Meldung krieg ich hin
Wie kann ich die Pin-Überwachung generieren?
Lass deinen Nachtwächter sich Notiz-Zettel schreiben
Merkst du dir die Zeit des letzten Wechsels des CLK PIN. Wenn diese länger als x ms her ist und der Pin die ganze Zeit HIGH ist, ist gar kein Messschieber dran. Dann kannst du die Störungslampe anmachen und loop() ist fertig. Wenn der Pin die ganze Zeit LOW war, bist du bereit, beim nächsten Wechsel mit der Erfassung zu beginnen.
Und versuche, nicht in Prozeduren zu denken, sondern in Zustandsbeschreibungen.
Wenn loop keine Zeit braucht und dafür unendlich schnell läuft, bist du auf dem richtigen Weg.
INPUT_PULLUP kannst du ohne weiteres zusätzlich benutzen. Dann kannst du auch die Leitung zum Transistor abziehen, ohne dass der Pin Schrott-Signale erkennt.
Ich habs jetzt recht pragmatisch gelöst, aber so, dass es für meine Zwecke funktioniert:
ich frage einfach zu Beginn mit einer while-Schleife ab, ob am CLK-Pin ein Wechsel von HIGH (durch den internen Pullup ja konstant auf 5V gezogen, wenn der Transistor sperrt) auf LOW stattfindet. Sobald dies der Fall ist gehe ich davon aus, dass die Uhr angeschlossen UND angeschaltet ist. Dann setze ich eine Variable init_flag auf 1, die in einer IF-Schleife als Ausführbedingung genutzt wird.
Diese IF-Schleife dekodiert dann das binäre Signal.
int i;
int sign;
long value;
float result;
int clockpin = 2;
int datapin = 3;
unsigned long tempmicros;
int init_flag;
void setup() {
Serial.begin(9600);
pinMode(clockpin, INPUT_PULLUP);
pinMode(datapin, INPUT_PULLUP);
}
void loop () {
while(digitalRead(clockpin)==HIGH) { //warte auf CLK Wechsel von LOW zu HIGH (Signal invertiert)
init_flag = 0; // Uhr nicht initialisiert
Serial.println("Uhr nicht initialisiert");
}
init_flag = 1;
if (init_flag==1) {
while (digitalRead(clockpin)==HIGH) {} //if clock is LOW wait until it turns to HIGH
tempmicros=micros();
while (digitalRead(clockpin)==LOW) {} //wait for the end of the HIGH pulse
if ((micros()-tempmicros)>2000) { //if the HIGH pulse was longer than 2000 micros we are at the start of a new bit sequence
decode(); //decode the bit sequence
}
}
}
void decode() {
sign=1;
value=0;
for (i=0;i<23;i++) {
while (digitalRead(clockpin)==HIGH) { } //wait until clock returns to HIGH- the first bit is not needed
while (digitalRead(clockpin)==LOW) {} //wait until clock returns to LOW
if (digitalRead(datapin)==LOW) {
if (i<20) {
value|= 1<<i;
}
if (i==20) {
sign=-1;
}
}
}
result=(value*sign)/100.00;
Serial.println(result,2); //print result with 2 decimals
delay(1000);
}
Trotzdem danke für die Nachtwächter-Variante, das war sehr gut erklärt und lässt sich sicherlich in zukünftigen Projekten (abgewandelt) einsetzen.
Vielen Dank für die Hilfe und schöne Osterfeiertage