[KSP Hardware] Arduino-Code funktioniert nicht...

  • Hallo Ihr da draußen!
    Ich arbeite gerade an einem Steuerpult und wollte jetzt ein einfaches Programm schreiben, das,
    immer wenn ein Schalter umgelegt wird eine Taste gedrückt wird.
    wenn der Schalter also auf Ein steht, soll in KSP das SAS eingeschaltet sein, sobald ich den Schalter umlege soll der Arduino Micro, der eine Tastatur emuliert, die S-Taste drücken, um das SAS auch in KSP auszuschalten.
    Allerdings sieht es so aus, als würde der Arduino dauerhaft S gedrückt halten... :thumbdown:
    Jedenfalls ist innerhalp von ein paar Sekunden eine ganze Seite vollgeschrieben.
    Hat jemand von euch eine Idee? An der Hardware kann es eigentlich nicht liegen, da ich auch schon Pin 2 (Signal-Eingang) und GND (Erdung) über einen 1K?-Widerstand verbunden habe, also sich für den Arduino der Input nicht ändern sollte, und immernoch das gleiche Problem war.


    Hier ist noch der Code:


    Das ist kein Bug, das ist ein Feature !
    ---------------------------------------------------------
    Wie Geht es so?

  • So ?


    Das ist kein Bug, das ist ein Feature !
    ---------------------------------------------------------
    Wie Geht es so?

  • genau zum beispiel



    was es auch noch sein könnte ... wobei ich nicht weiss wie das bei c++ ist


    das er einen typen vergleich macht


    was ich meine


    digitalRead(2); gibt einen bool wert zurück true oder false


    int SASState=digitalRead(2); //konvertiert diesen bool wert in ein int 1 oder 0

    1 ist ungleich true



    darum könnte es sein das er immer in die schleife rein geht
    aber ich weiss halt nicht wie das da mit den datentypen ist


    eine lösung wäre



    int newStat = digitalRead(2);
    if (newStat!=SASState) {
    ....
    SASState = newStat;
    ....
    }

    alles wird Troll

  • Dich schickt der Himmel, es funktioniert !
    Deine zweite Idee hat gestimmt.
    Ich weiss zwar nicht warum das andere nicht funktioniert aber auf jeden Fall geht es jetzt !


    Hier der funktionierende Code:




    Danke !

    Das ist kein Bug, das ist ein Feature !
    ---------------------------------------------------------
    Wie Geht es so?

  • kein ding ... dafür mach ich das ja schon 16 jahre lang :D


    nur C is ewig her ^^


    wobei laut doku gibt die funktion auch nen int zurück
    aber egal ... wenns geht dann gehtz :D


    trotzdem noch nen delay(50); vor das if ;) und das im if raus nehmen


    schont die CPU ^^


    ggf kannst du da auch noch höher/niedriger stellen .... wenn du nicht alle grade alle paar millisekunden an dem armen schalten rum nudeln willst ^^

    alles wird Troll

  • nächstes Problem...
    Ich will die Zweifarben-LED so dimmen, so dass sie immer rötlicher wird, je leerer der Tank ist.


    Hier ist der ausschnitt vom Code, der für das dimmen verantwortlich ist:

    Code
    1. float Fpercent;
    2. float FpercentOut;
    3. float FpercentInv;
    4. Fpercent = (VData.LiquidFuelS*VData.LiquidFuelTotS)/100;
    5. FpercentOut = Fpercent * 2,55 ;
    6. FpercentInv = 255 - FpercentOut;
    7. analogWrite(FLEDM,FpercentOut);
    8. analogWrite(FLEDL,FpercentInv);


    das soll so funktionieren, dass FpercentOut (Fuel Prozent) immer kleiner wird und FpercentInv (Fuel Prozent Invertiert) immer größer. Davor wird Fpercent mit 2,55 multipliziert, dass es für den analog Out passt, da dieser mit Werten von 0-255 arbeitet. Mein Problem ist:
    Die LED ist nicht am Anfang frün und wenn der Tank alle ist Rot, sondern dieses dimmen läüft drei mal, d.h. es läuft zwei mal wieder von vorne durch... Habt ihr eine Idee ?

    Das ist kein Bug, das ist ein Feature !
    ---------------------------------------------------------
    Wie Geht es so?

  • Ich programmiere selber 8bit-AVRs, allerdings nicht Arduinos sondern direkt in C mit dem avr gcc. Deshalb kenne ich die Aduino Lib nicht. Aber vielleicht kann ich ja trotzdem etwas helfen.


    Ich finde die Idee mit der Duo-LED ziemlich cool. Bestimmt besser als eine LED-Reihe oder so, wobei ich intuitiv doch lieber eine dreistellige 7-Segment-Anzeige mit "echten" % favorisieren würde. Aber egal, erstmal was zu deiner Rechnung:
    Du nimmst ein float, stopfst da die aktuellen Prozent rein und skalierst sie auf 8Bit für den Analogen Ausgang, korrekt?
    Und wenn du den Tank von 100% bis 0% leerbrennst, durchläuft die LED drei mal den Durchgang grün->rot? Mein erster Gedanke, dir läuft da irgendwo eine Variable über oder die Rechnung ist nicht korrekt.


    Ich glaube, es hakt an der Rechnung. Ist das richtig, VData.LiquidFuelS ist dein aktueller Spritstand und VData.LiquidFuelTotS die Gesamtkapazität? Wenn ich für
    Fpercent = (VData.LiquidFuelS*VData.LiquidFuelTotS)/100;
    beispielsweise (50*100)/100 rechne, kommt noch 50 raus. Wenn ich (500*1000)/100 rechne, nicht mehr. Mach das mal so:

    Code
    1. Fpercent = (VData.LiquidFuelS/VData.LiquidFuelTotS)*100;


    Damit hast du dann die korrekten Prozent.


    Wozu eigentlich mit Fließkommaarithmetik arbeiten? So genau kann man das auf der Duo-LED garnicht sehen. Da kannst du auch geschickt umstellen und ohne Komma rechnen, analog wird es eh ein 8bit unsigned int. Sparrt ne Menge Ressourcen. Versuch das mal so (vorrausgesetzt, analogWrite() kommt damit klar):


    Code
    1. unsigned int FpercentOut;
    2. unsigned int FpercentInv;
    3. FpercentOut = VData.LiquidFuelS / VData.LiquidFuelTotS * 255;
    4. FpercentInv = 255 - FpercentOut;
    5. analogWrite(FLEDM,FpercentOut);
    6. analogWrite(FLEDL,FpercentInv);


    BTW, schreibt man bei Arduino floats mit einem Komma? Ich hätte 2.55 erwartet, nicht 2,55.



    Zum SAS will ich auch nochmal was loswerden:
    Ich wundere mich, warum du überhaupt integer für den SAS-Status brauchst, wenn du einen Schalter hast. Der digitale Input- Pin hat doch immer den aktuellen (Soll-)Zustand anliegen.
    Ich würde den einfach via Timerinterrupt alle 10ms einlesen (Zum entprellen). Ist er HIGH, ist SAS an, ist er LOW ist es aus.
    Dann hast Du doch sicher irgendwo eine LED, die das anzeigt. HIGH an, LOW aus, oder so.
    Somit zeigt der Eingangspin am Schalter immer den Sollzustand und der Ausgangspin an der LED den Istzustand. Unterscheiden sie sich, muss ein 'S' seriell gesendet werden. Einfach die beiden Hardware-Pins maskieren und vergleichen.

  • trotzdem noch nen delay(50); vor das if ;) und das im if raus nehmen


    schont die CPU ^^

    Öh, nö, tut es nicht. Die delay() muss in die if-Abfrage, denn sicherlich wird in der loop später noch mehr abgearbeitet, und die Verzögerung ist nur notwendig, wenn die Taste gedrückt wird. Sonst klettert die MCU ja jeden Schleifendurchlauf ins Hamsterrad. Außerdem stinken delay()-Funktionen. Ok, ich nutze sie auch gelegentlich, aber nicht in oft wiederkehrenden Funktionen. Da würde ich wärmstens empfehlen, sich mit einem Timer und seinem Overflow-Interrupt eine Tasterabfrage zu basteln.

  • cino das benutze ich ja auch, das was ich geschrieben habe war nur ein Ausschnitt weil der Rest sowieso irrelevant war ;)
    Mullwark Danke! Irgendwo hatte ich das mit der Prozentrechnung falsch gelesen und nicht nachgerechnet... Ausserdem muss ich es irgendwie hinkriegen dass die Stärke der LED`s gleichmässig ansteigt... Im Moment
    ist das dimmen nicht gleichmässig sondern am Anfang passiert nichts und bei der Hälfte geht es dann auf einmal fast komplett an... So etwa:



    Code
    1. /--------------
    2. /
    3. /
    4. /
    5. /
    6. /
    7. -----------/


    Das soll die Kurve sein :D :P

    Das ist kein Bug, das ist ein Feature !
    ---------------------------------------------------------
    Wie Geht es so?

    Einmal editiert, zuletzt von KASA ()

  • Im Moment
    ist das dimmen nicht gleichmässig sondern am Anfang passiert nichts und bei der Hälfte geht es dann auf einmal fast komplett an...

    Die Helligkeitswahrnehmung unserer Augen ist annähernd logarithmisch. Ich habe gelesen, daß es beim Dimmen von LEDs zu einem guten Ergebnis kommt, wenn man eine logarithmische Tabelle zugrunde legt. Habe aber bisher nur linear gedimmt und ein ähnliches Verhalten wie du wahrgenommen. Wie sich das beim Mischen von Rot und Grün verhält, kann ich nicht sagen.

  • Der fünfte in diesem Beitrag schreibt ja etwas über seine Dimmstufen. http://www.mikrocontroller.net/topic/43922 Wie kann man diese ins Programm bringenc? wenn das funktioniert sollte das dimmen ja eigentlich
    linear aussehen... Oder ? :huh:
    So sind die Werte:

    Code
    1. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 18, 20, 22, 25,28, 30, 33, 36, 39, 42, 46, 49, 53, 56, 60, 64, 68, 72, 77, 81, 86, 90,95, 100, 105, 110, 116, 121, 127, 132, 138, 144, 150, 156, 163, 169,176, 182, 189, 196, 203, 210, 218, 225, 233, 240, 248, 255


    dann müsste ich die Prozent aber in 64stel umrechnen,oder nicht ?
    Kann ich irgendwie eine Tabelle erstellen und die Werte der Reihe nach aufrufen ?
    oder geht es mit etwas wie

    Code
    1. LEDLIGHT = 1/Fpercent;
    2. analogWrite(FLEDM,LEDLIGHT);

    ?
    Ausserdem ist die grüne LED irgendwie schwächer... Ich müsste mal ein bisschen mit den Vorwiederständen experimentieren...


    Was genau macht diese Formel? Ich raff sie nicht. ;( Ist die wichtig ? und gibt es irgend eine Formel für diese Kurve ?

    Das ist kein Bug, das ist ein Feature !
    ---------------------------------------------------------
    Wie Geht es so?

    4 Mal editiert, zuletzt von KASA ()

  • dann müsste ich die Prozent aber in 64stel umrechnen,oder nicht ?

    Ich habe jetzt nicht nachgezählt, ob die Tabelle 64 Elemente hat, aber ja, du hast nicht mehr 255 Schritte sondern nur so viele, wie Tabellenelemente.

    Zitat

    Kann ich irgendwie eine Tabelle erstellen und die Werte der Reihe nach aufrufen ?

    Ja, du nimmst array, z.b. unsigned int fadingstep[0, 1, 2,...] und sprichst sie als fadingstep[x] an.


    In dem Beitrag erwähnt der Schreiber, daß er mit den Werten nicht 100% zufrieden ist. Ggf. musst du da auch selber etwas herumprobieren.
    Könnte sein, daß dir da die von dir gezeigte Kennlinie der LED hilft. Der Helligkeitszuwachs ist laut Grafik eben nicht linear. Da würde ich mit Excel bzw. OOCalc eine Wertetabelle erstellen und eine Regression machen lassen. Dann hast du eine Annäherung, die für die Anwendung genau genug sein müsste.


    Das Grün und Rot unterschiedlich hell sind, ist normal. Da könntest mittels Poti das Hellere soweit reduzieren, bis es optisch passt und dann den Widerstand messen.


    Die Formel unten würde ich erstmal außer acht lassen, wenn du eh mit einer Wertetabelle arbeitest.[/i]