Arduino, MoBa und wenig Ahnung

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    • Arduino, MoBa und wenig Ahnung

      Seid gegrüßt, Erdlinge,

      ich will mit dem Arduino eine Dezimalzahl in binär umwandeln und die Bits in einer einzeiligen Matrix speichern.
      Leider habe ich keine Idee, wie ich
      eine Dezimalzahl (0-254) in eine 8 stellige Binärzahl umwandeln kann
      die Binärzahl in eine Matrix schreiben kann um damit eine LED Reihe anzusteuern.

      Sollte einer von euch mir helfen wollen freue ich darauf; auf die Freischaltung in einem Arduino-Forum warte ich seit Tagen.
      Gruß vom Naboo und Dif-tor heh smusma!

      JarJar :spock:


      Als die Nazis die Kommunisten holten, habe ich geschwiegen; ich war ja kein Kommunist. Als sie die Sozialdemokraten einsperrten, habe ich geschwiegen; ich war ja kein Sozialdemokrat. Als sie die Gewerkschafter holten, habe ich geschwiegen, ich war ja kein Gewerkschafter. Als sie mich holten, gab es keinen mehr, der protestieren konnte.
      von Martin Niemöller
    • Hallo,

      also falls es dir in erster Linie um den Algorithmus geht, der steht beispielsweise auf dieser Seite ganz unten: Link

      Vom Arduino habe ich keine Ahnung und weiß auch nicht, in welcher Programmiersprache das Ganze passiert, aber die Umrechnung sollte sich auch da einfach in einer Schleife abarbeiten lassen. Dann benötigst du nur noch eine Funktion, die dir dein Ergebnis entsprechend in deine Matrix (Array) schreibt. Das wäre beispielsweise eine Möglichkeit, wie es sich realisieren lassen sollte.

      Gruß
      Christian
    • Hallo Christian,

      danke, aber der Alkoholrythmus ist nicht das Problem. Das Thema ist die Formulierung in dem C Dialekt.
      Gruß vom Naboo und Dif-tor heh smusma!

      JarJar :spock:


      Als die Nazis die Kommunisten holten, habe ich geschwiegen; ich war ja kein Kommunist. Als sie die Sozialdemokraten einsperrten, habe ich geschwiegen; ich war ja kein Sozialdemokrat. Als sie die Gewerkschafter holten, habe ich geschwiegen, ich war ja kein Gewerkschafter. Als sie mich holten, gab es keinen mehr, der protestieren konnte.
      von Martin Niemöller
    • Dann könntest du das mit einem int Array realisieren, was du mit acht Nullen initialisierst.

      Zwei Variablen als int noch für deine Dezimalzahl und deinen Rest.

      In einer While-Schleife arbeitest du den Algorithmus ab und speicherst dir die Einsen und Nullen in dein Array. Die Stelle des Arrays bekommst du über einen Zähler heraus, der die Schleifendurchläufe zählt.

      In einer weiteren Schleife musst du dann nur noch dein Array umdrehen.

      Damit hättest du dann eine Dezimalzahl in eine Binärzahl umgerechnet und in einem Array gespeichert. Gibt sicherlich noch schönere Lösungen, aber das sollte vergleichsweise einfach nachvollziehen zu sein.

      Gruß
      Christian
    • Hallo JarJar,

      ich bin zwar nicht der "Experte" und kann auch nicht sagen, ob das hier funktioniert,
      aber probiere das mal ...

      for (int i=0; i < 8; i++){

      digitalWrite(i, bitRead(x, i) );
      }

      Das ist c code und x ist die auszugebene Zahl ( Byte ) .
      i ist das Bit, dass von x abgefragt werden soll und mit digitalWrite auf PIN i ausgegeben wird.
      Sollte das PIN nicht i sein, kann auch noch digitalWrite(i +3, bitRead(x, i) ); oder so verändert werden.
      Ist das i te Bit von x gesetzt, wird eine 1 ausgegeben, sonst wird eine 0 ausgeben.

      Gruß Ralf

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von ralfbahn ()

    • Servus,

      danke für eure bisherigen Hilfen. Sieht bisher ganz gut aus.
      Die Bits landen zuerst in einem Zwischenarray (LSB links statt rechts) und werden dann richtig sortiert:

      bm80[0]=bm80f[7]; //Reihenfolge des Arrays bm80 korrigieren
      bm80[1]=bm80f[6];
      bm80[2]=bm80f[5];
      bm80[3]=bm80f[4];
      bm80[4]=bm80f[3];
      bm80[5]=bm80f[2];
      bm80[6]=bm80f[1];
      bm80[7]=bm80f[0];

      Gibt es für diese "Arbeit" eine elegantere Lösung? Wenn ich das für mehrere Arrays mache kenne ich mich in dem Code nicht mehr aus...
      Gruß vom Naboo und Dif-tor heh smusma!

      JarJar :spock:


      Als die Nazis die Kommunisten holten, habe ich geschwiegen; ich war ja kein Kommunist. Als sie die Sozialdemokraten einsperrten, habe ich geschwiegen; ich war ja kein Sozialdemokrat. Als sie die Gewerkschafter holten, habe ich geschwiegen, ich war ja kein Gewerkschafter. Als sie mich holten, gab es keinen mehr, der protestieren konnte.
      von Martin Niemöller
    • Hallo Ralf,

      das ist zu einfach! Oberdoppelmist. Ich bin und bleibe ein mathematischer Banause. Herzlichen Dank dafür.
      Das mit dem Zwischenarray habe ich deshalb, weil ich gedanklich noch nicht in der Lage war, das gleich richtig zu machen.
      Aber Dank Deines Hinweises haben sich jetzt ein paar Knoten aus Hirn und Zunge gelöst, so dass ich ganz zuversichtlich bin, die
      Problemstellung eleganter zu lösen.
      Gruß vom Naboo und Dif-tor heh smusma!

      JarJar :spock:


      Als die Nazis die Kommunisten holten, habe ich geschwiegen; ich war ja kein Kommunist. Als sie die Sozialdemokraten einsperrten, habe ich geschwiegen; ich war ja kein Sozialdemokrat. Als sie die Gewerkschafter holten, habe ich geschwiegen, ich war ja kein Gewerkschafter. Als sie mich holten, gab es keinen mehr, der protestieren konnte.
      von Martin Niemöller
    • Hallo zusammen

      Es ist mir klar, dass ich ziemlich spät dran bin, aber als eben erst dazugekommener, alter Software-Heini kann ich es schlicht nicht unterlassen, hier auch noch meinen Senf beizusteuern. Also: Zahlen sind in einem Computer sowieso immer digital gespeichert und so geht es - ohne irgendwelche Umrechnereien - nur darum, bei einem gegebenen Wert die einzelnen Bits zu detektieren und die Information in einem Array (= eindimensionale Matrix) abzulegen. In C/C++ zum Beispiel so:

      #define BITS 8 // oder 16 oder 32, je nach Anwendung
      int value, bit, index;
      int array[BITS];

      value = ... // der zu untersuchende Wert
      for (bit = 1, index = 0; index < BITS; ++index, bit <<= 1)
      array[index] = (value & bit) ? 1 : 0; // das Zeichen zwischen 'value' und 'bit' ist das bitweise UND

      Das 'bit' wird also einfach durch den Wert hindurchgeschoben und dazu benutzt, die einzelnen Bits des Wertes herauszumaskieren. Soll die Speicherung in umgekehrter Reihenfolge geschehen, dann schreibt man einfach
      array[BIT - 1 - index] = ...

      Nüüt för uuguet
      Der Weg ist das Ziel ...
    • Hallo Sugus,

      also ... bis hierhin komme ich noch mit ...

      #define BITS 8 // oder 16 oder 32, je nach Anwendung

      int value, bit, index;

      int array[BITS];



      value = ... // der zu untersuchende Wert

      ....

      Aber das könntest du bitte mal genauer erklären ...

      for (bit = 1, index = 0; index < BITS; ++index, bit <<= 1)

      array[index] = (value & bit) ? 1 : 0; // das Zeichen zwischen 'value' und 'bit' ist das bitweise UND

      array[BIT - 1 - index] = ...


      Gruß Ralf
    • Also, dann wollen wir mal tief einatmen ...


      (1) Erklärung zu "bit <<= 1"

      Den Operator << gibt's (zumindest) in den Programmiersprachen C, C++ und Java und

      bit <<= 1

      ist die kompaktere Schreibweise für

      bit = bit << 1

      (Analog etwa ist/war auch x += 7 statt x = x + 7 die "bessere" Variante).

      Der Einfachheit halber nehmen wir mal an, dass wir es mit Integergrössen aus 8 Bits zu tun haben. Dann würde beispielsweise der Wert 105 bitweise (d.h. binär oder digital) als

      01101001

      gespeichert, was mathematisch soviel wie

      0 * 2^7 + 1 * 2^6 + 1 * 2^5 + 0 * 2^4 + 1 * 2^3 + 0 * 2^2 + 0 * 2^1 + 1 * 2^0


      oder

      0 * 128 + 1 * 64 + 1 * 32 + 0 * 16 + 1 * 8 + 0 * 4 + 0 * 2 + 1 * 1 = 105

      bedeutet.

      Das Bit ganz links ist das höchstwertige und jenes ganz rechts das niedrigstwertige. Wird auf diesen Wert nun die Operation << 1 bzw. "Shift Left 1" ausgeführt, dann werden alle Bits um eine Position nach links (bzw. in der Wertigkeit nach "oben") geschoben. Rechts (also wertigkeitsmässig ganz unten) wird eine Null reingedrückt, während das zuvor höchstwertige Bit links schlicht und einfach im Nirwana verschwindet. Aus

      01101001

      es entsteht mit

      11010010

      auf diese Art und Weise der Wert 210 und man stellt fest, dass << im wesentlichen den Integerwert verdoppelt. Ganz analog erreicht man mit >> (Shift Right) eine Werthalbierung. Selbstverständlich gilt dies nur begrenzt, weil ja auf der einen Seite jeweils ein Bit verschwindet und auf der anderen Seite eine Null hereinspaziert. Die Geschichte ist also nach maximal 8 Operationen beendet und wir landen beim Wert

      00000000

      Die Zahl nach << bzw. >> legt die Anzahl der Shift-Operationan fest.

      In unserer Anwendung geht es jedoch nicht um eine Wertverdoppelung, sondern wird wollen das maskierende 'bit' ganz einfach durch alle Positionen hindurchschieben, um damit zu prüfen, ob das entsprechende Bit im 'value' gesetzt ist oder nicht.

      Die Operatoren << und >> wurden in C eingeführt, um die mit den (damaligen) Prozessoren möglichen Shift Operationen direkt abbilden zu können. (Näheres hierzu würde wohl ein "googlen" nach "Die Geschichte von C und UNIX" zutage fördern.) Eine Shift-Operation ist für einen Prozessor nämlich um ein Vielfaches einfacher als eine Multiplikation, und so war es etwa bei der Ansteuerung von Grafikkarten eben üblich, darauf zurück zu greifen. Statt der damals üblichen Multiplikation mit 80 wurde dann die viel effizientere Variante

      (Wert << 6) + (Wert << 4) oder eben "Wert mal 64" plus "Wert mal 16"

      programmiert.


      (2) Erklärung zu "... ? 1 : 0"

      Die bereits oben erwähnten Programmiersprachen kennen den sog. "Bedingten Ausdruck" (mit Fragezeichen und Doppelpunkt), d.h. syntaktisch das Gebilde

      <Ausdruck1> ? <Ausdruck2> : <Ausdruck3>

      welches quasi einem IF ... THEN ... ELSE ... entspricht. Je nachdem ob der boolsche <Ausdruck1> wahr oder falsch ist, wird als Wert das Gebildes <Ausdruck2> oder eben <Ausdruck3> herangezogen. Für uns heisst dies mit

      (value & bit) ? 1 : 0

      dass wir im Array-Element eine 1 speichern, wenn 'value & bit' einen Treffer liefert (das entsprechende Bit also gesetzt ist), und eine 0 andernfalls.


      (3) Erklärung zu "array[BIT - 1 - index]"

      Zunächst muss ich um Verzeihung bitten: es muss selbstvertändlich BITS heissen, nicht BIT.

      Wenn 'index' vorwärts von 0 bis 7 läuft, dann tut's (mit "#define BITS 8") der Ausdruck 'BITS - 1 - index' ganz einfach von 7 bis 0 rückwärts, wodurch die Elemente des Arrays dann dirket in umgekehrter Reihenfolge angesprochen werden.


      Hoffe hiermit gedient zu haben :)
      Sugus
      Der Weg ist das Ziel ...

      Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von Sugus ()

    • Hallo Sugus,

      vielen Dank für die ausführliche Beschreibung ... :thumbsup:
      Ein enfaches "<<=" bedeutet linksverschieben hätte mir da schon gereicht bzw. bit <<=1 oder bit <<=3 bedeutet den Inhalt von bit links um ein oder drei Bit verschieben ... verstehe ich auch devil
      Das <Ausdruck1> ? <Ausdruck2> : <Ausdruck3> quasi einem IF ... THEN ... ELSE ... entspricht habe ich nicht gewusst. :wacko:
      So gut kenne ich mich da nicht aus. Hat diese Schreibweise einfluss auf den Compilerlauf? Denn aus Lesbarkeitsgründen würde ich dann doch lieber » IF ... THEN ... ELSE ... « schreiben.
      Man muss sein Code auch noch später lesen und ändern können ...

      Ein "array[BIT - 1 - index]" entspricht also ein "FOR x=10 to 0, step -1" - Schleife ...




      Ich werde bestimmt noch mal ein paar Frage haben und es ist gut zu wissen, dass hier jemand richtig Ahnung hat ... und einem weiter geholfen werden kann ...

      Gruß Ralf
    • Hallo Ralf

      Ich denke, dass Du's nun im Kasten hast! Ob IF-THEN-ELSE oder ?: ist Geschmacksache und bei den heute benutzten Compilern i.a. nicht mehr relevant, weil letztere sowieso optimieren, wo sie nur können. Früher war das halt mal anders ...

      Und selbstverständlich bin ich gegenüber weiteren Fragen rund um die Programmiererei (mit C/C++ oder Java) offen.

      Gruss
      Sugus
      Der Weg ist das Ziel ...
    • Seid gegrüßt,

      hatte wieder Lust mich mit dem Arduino und der Steuerung/Anzeige eines Anlagenteils zu beschäftigen.
      Die Ports 88 und 89 sind die Taster bzw. Anzeigen für die Weichen; die Ports 97 und 91 zeigen die Beleung eines Blockes an.
      Zur Verbindung mit der MoBa möchte ich die Lib von opensx nutzen (opensx.net).

      Prompt stehe ich vor einem Problem; mir gehen die Anschlüsse aus:
      Schaltplan lSch V1.PNG


      Wie kriege ich die Ports 2 und 4 frei?
      Gruß vom Naboo und Dif-tor heh smusma!

      JarJar :spock:


      Als die Nazis die Kommunisten holten, habe ich geschwiegen; ich war ja kein Kommunist. Als sie die Sozialdemokraten einsperrten, habe ich geschwiegen; ich war ja kein Sozialdemokrat. Als sie die Gewerkschafter holten, habe ich geschwiegen, ich war ja kein Gewerkschafter. Als sie mich holten, gab es keinen mehr, der protestieren konnte.
      von Martin Niemöller
    • Seid gegrüßt,

      ich verwende KATO Weichen. Keine Endabschaltung. Ist aber auch m.E. unwichtig, da ich mit den Tastern ja nur der Zentrale sage, ich hätte gerne den Weichendecoder überredet, die Weiche zu schalten.
      Oder sehe ich das falsch?
      Gruß vom Naboo und Dif-tor heh smusma!

      JarJar :spock:


      Als die Nazis die Kommunisten holten, habe ich geschwiegen; ich war ja kein Kommunist. Als sie die Sozialdemokraten einsperrten, habe ich geschwiegen; ich war ja kein Sozialdemokrat. Als sie die Gewerkschafter holten, habe ich geschwiegen, ich war ja kein Gewerkschafter. Als sie mich holten, gab es keinen mehr, der protestieren konnte.
      von Martin Niemöller
    • Hallo JarJarBinks

      Ich besitze keinen Arduino und kenne das Ding auch nicht, weil ich meine Elektronik selber zusammen bastle und dann alles vom PC aus via USB über ein TTL-I/O Modul (von DEDITEC) steuere.

      Ich kann daher leider nur helfen, wenn es um's Programmieren in C, C++ oder Java geht.

      Ich sehe aber mit Freuden, dass es im Forum Leidensgenossen gibt und Du daher wohl gut beraten wirst.

      Gruss vom Bodensee
      Sugus
      Der Weg ist das Ziel ...
    • Hallo JarJar,

      siehst Du in sofern richtig, wenn Du Deinen Weichendecoder einprogrammiert hast, wie lange der Ausgang schalten soll. Dann ist alles bestens.




      LG Mario :ks:
      Ohne Fleiss kein Bandscheibenvorfall ! :cursing:
      Modellbahn Spur N, Roco, Minitrix Gleise und Weichen, Weichensteuerung über Servos mit Steuerung von MB-Tronik und 4-fach Servodecoder von DIGIKEIJS, Intellibox II & IB-Control II zum Fahren DCC und SX I gemischt , IB-Com zum Schalten & Melden, S88-Module von DIGIKEIJS mit Uhlenbrockadapter auf Loconet, Drehscheibensteuerung über Fleischmann Turn-Control, WinDigipet Premium 2015. :ks: :ks: