Jump to content

Recommended Posts

Posted
W dniu 29.12.2024 o 16:00, pomiary.el1 napisał(a):

Cześć,

Odnalazłem ten wątek w celu zadania pewnego pytania ale już chyba niestety znam odpowiedź 😞 Zbudowałem pulpit od EN57, w zasadzie część ślusarsko spawalnicza oraz elektryczna jest już na ukończeniu, ale zaczynam powoli pracę związaną z uruchomieniem manometrów, prędkościomierza i ogólnej komunikacji gry z sygnalizacją SHP, lampkami oraz miernikami. Z tego co tu czytam i widzę po Waszych pulpitach, twórcy gry pomimo szumnych zapowiedzi zrobili nas w balona. Liczyłem, że po wyjściu z EA będzie jakaś informacja zwrotna dla kontrolerów i wsparcie dla pulpitów , a tu jak zwykle dupa 😞  

Pochwalę się i ja, efektem wielomiesięcznej pracy:   

IMG_20240613_163556_690.jpg

img_20241229_152759_756.jpg

img_20241229_152809_355.jpg

img_20241229_152947_595.jpg

img_20241229_153110_890.jpg

img_20241229_153003_317.jpg

img_20241229_152851_993.jpg

Zazdroszczę! za oryginalny hardware 🙂, spory klamot, ale będzie frajda z tego.

Posted (edited)
31 minut temu, Conrad napisał(a):

Świetnie! Jak rozumiem byłaby szansa na bypass pomiędzy SimRail, a wyjściem na zewnątrz i przekazywaniem stanów na swój hardware!?

Do tego się dokopałeś (pod F8) ?

Pierwszy raz widzę to okno... 😄 To jakiś tryb developerski?

Nie wiem jak sie steruje silnikami krokowymi. Jeśli tak, że jakaś dana wartość przesuwa silniczek to tak, to możliwe.

 

Wartości z amperomierzy zostały pobrane z pamięci Simrail.exe a konkretniej z biblioteki GameAssembly.dll i z określonym odpowiednim offsetem bazowym i offsetami wartości. Jest to problematyczne, bo adresy są dynamiczne i zmieniają się z każdym uruchomieniem gry. Ale znając offset bazowy można określić gdzie znajduje się szukana wartość - aczkolwiek raz na 5-10 razy to nie działa. Żeby to naprawić musiałbym wpisać logikę która korzysta np z zapasowego adresu (albo najlepiej 10 po kolei aż nie znajdzie działającego adresu).  Program napisany w Phyton przy użyciu .pymem który wyciąga wartości z gry i .flask który tworzy serwer i w sieci lokalnej można wyświetlić wyniki za pomocą html JavaScript ajax np. na tablecie jak u na moim filmie. 

Jak za rok twórcy nie udostępnią API to będziemy pisać 😄

Edited by JarkPomsky
  • Like 2
Posted
19 godzin temu, JarkPomsky napisał(a):

Nie wiem jak sie steruje silnikami krokowymi. Jeśli tak, że jakaś dana wartość przesuwa silniczek to tak, to możliwe.

Co do silników krokowych to @Maciej_ZG już wcześniej podpowiedział jakie rozwiązanie się u niego sprawdziło. Tanie i często stosowane silniczki krokowe w projektach diy, często używane przy budowie kokpitów samolotów dla zegarów analogowych. np. do Cessny. Łatwo znaleźć gotowe rozwiązania i tutoriale diy.

Co do API od dev to obecnie moja nadzieja szoruje po dnie pustego basenu 🤣

Posted
51 minutes ago, Conrad said:

Co do silników krokowych to @Maciej_ZG już wcześniej podpowiedział jakie rozwiązanie się u niego sprawdziło. Tanie i często stosowane silniczki krokowe w projektach diy, często używane przy budowie kokpitów samolotów dla zegarów analogowych. np. do Cessny. Łatwo znaleźć gotowe rozwiązania i tutoriale diy.

Co do API od dev to obecnie moja nadzieja szoruje po dnie pustego basenu 🤣

Jakby co to mogę udotępnić kod Arduino na którym te silnicznki u mnie działają

Posted

Ogólnie to gra przechowuje w pamięci konkretną wartość np dotyczącą napięcia (np. 235), a dla np. SHP/CA jest 1 albo 0.  

Posted
W dniu 2.01.2025 o 18:14, Conrad napisał(a):

Zazdroszczę! za oryginalny hardware 🙂, spory klamot, ale będzie frajda z tego.

Niestety bardzo mnie ta kolubryna przerosła. Niby jest na kółkach, wszystkie wystające części są demontowalne, a ich zasilanie realizowane jest poprzez gniazda. Można też zdemontować nogi - mocowane na motylki. Niemniej jednak sama skrzynia z zawartością waży prawie 100 kilo.  Ogólnie kiepski pomysł aby takie coś stało w mieszkaniu. O wściekłej żonie nie wspomnę 😞 

Jeśli ktoś byłby zainteresowany historią powstawania pulpitu od samego początku, to zapraszam tu: https://rcn.tlx.pl/forum/viewtopic.php?f=31&t=760&sid=021b2ce0f8c68348daf3677dec143bc7 

Wada jest taka, że  niestety polityka tamtego forum wymaga zalogowania.

Plus - masa zdjęć z każdego etapu  budowy pulpitu oraz różnych problemów, które codziennie napotykałem. Również  rozwiązań, które ciągle trzeba było zmieniać i ulepszać metodą prób i błędów.

 

Pozdrawiam

Łukasz 

PS.

Sporo mam części rezerwowych takich jak przełączniki typu "Z", lampki LS48, przyciski, nawet jeden nastawnik hamulcowy się ostał.   Gdyby ktoś, kiedyś coś...

 

  • Like 2
Posted (edited)

Jeśli chcesz spróbować pobawić się i podłączyć pulpit, to załączam program do odczytu pamięci Amperomierza WN2 w EU07.

Wyciąga on dane i umieszcza w formacie JSON na adresie hosta. Możesz przetestować po uruchomieniu wbijając w przeglądarkę:

http://192.168.0.13:5000/api/receive_data  -  zamień adres IP na swój adres lokalny - https://i.imgur.com/Xk7m3ML.jpeg

Zarówna gra jak i ten program MUSZĄ być uruchomione z uprawnieniami administratora - bez tego program nie uzyska dostępu do pamięci.

Kod programu znajduje się tutaj: https://pastecode.io/s/c602k1rq

Po uruchomieniu powinieneś otrzymać coś takiego: https://i.imgur.com/gjOtTpK.jpeg

Skan antiwirusowy - niektóre antywirusy zgłaszają wirusa, to dlatego że aplikacja pobiera dane z procesu innej aplikacji (w tym przypadku z naszej gry) : VirusTotal - File - b7dc95461c754ef9fbe6c051ae831749d52e60775568297a43d8fe846e5984f7

Jak to zadziała to pomyślimy dalej.

 

Edit: Jak SimRail.exe nie jest włączony to program zamula kompa, za dużo razy szuka procesu 😄 ale już nie będę poprawiał teraz 😄

main.7z

Edited by JarkPomsky
  • Like 3
Posted

Spróbuje znaleźć trochę czasu w przyszłym tygodniu i dodać support do requestów HTTP i json'a. Rozumiem że to i tak na chwilę obecną działa tylko w jedną stronę, czyli można jedynie odczytać dane z mierników itp. ?

 

Posted (edited)

Tylko odczyt. Próbowałem wstrzykiwać inne wartości do pamięci, ale gra je liczy ileś tam razy na sekundę i momentalnie zastępuje je prawidłowymi. Wszystkie mierniki / kontrolki / można odczytywać - w zasadzie wszystko co jest pod F8 (dzięki @Conrad za uświadomienie, że istnieje coś takiego :D)

Edited by JarkPomsky
Posted

Jak tylko odczyt to wciąż tylko połowiczny sukces, bo trzeba by emulować naciskanie klawiszy klawiatury przy odczytywanieu danych z fizycznego pulpitu...

Posted
9 godzin temu, Maciej_ZG napisał(a):

Jak tylko odczyt to wciąż tylko połowiczny sukces, bo trzeba by emulować naciskanie klawiszy klawiatury przy odczytywanieu danych z fizycznego pulpitu...

Niestety tylko na razie tędy droga, ale kolejne elementy pulpitu ożyją. 

Posted
10 godzin temu, JarkPomsky napisał(a):

Tylko odczyt. Próbowałem wstrzykiwać inne wartości do pamięci, ale gra je liczy ileś tam razy na sekundę i momentalnie zastępuje je prawidłowymi. Wszystkie mierniki / kontrolki / można odczytywać - w zasadzie wszystko co jest pod F8 (dzięki @Conrad za uświadomienie, że istnieje coś takiego :D)

W weekand sprobuję to przetestować i dam znać co się udało uzyskać.

  • Like 1
Posted (edited)
On 1/4/2025 at 1:22 AM, pomiary.el1 said:

I have a lot of spare parts like "Z" switches, LS48 lights, buttons, even one brake controller is left. If someone ever...

I'd really like to buy some real Polish train parts (i'd really love to buy the entire driving desk from a train similar to the EU07) 

But the problems i have had before when trying to buy parts from Poland is i live in the UK 😞 and that silly brexit thing we had has made it more complicated for people in europe to send things here now, having to fill in customs forms and all that (which i always offer to pay extra for the persons time to do that, and of course cover all shipping costs) 

Then uk customs tries to charge me import duties and UK VAT (taxes) for second hand scrap parts i buy before they will deliver the items to me (i've bought old bus parts from Germany before for my Omsi driving cab) but i am getting used to that now, and know that 'second hand parts from scrapped vehicles' should not be taxed, but that's something for me to deal with, not the seller. 

I did try to buy some EN57 parts last year, but was told they would not send them out of Poland, seem's i am a minority being an english person who lives Polish trains thanks to SimRail. 

-----

Sorry for writing in english in the Polish section, i've been told in the past not to use google translate and try to post in a language i can't speak, as it's better to let the reader of the post translate the english text themselves. 

Edited by Gazz292
  • Like 1
Posted (edited)

@JarkPomsky  właśnie udało mi się przekazać dane z JSON do arduino 🙂

 

Na razie zrobiłem test zapalania się lampki LED kiedy wartość przekroczy >100 z tego co opublikowałeś

Kod dla Arduino Leonardo (8bit)

 
#include <ArduinoJson.h>

// Pin dla diody LED
const int ledPin = 10;

// Zmienna do przechowywania ostatniego czasu
unsigned long previousMillis = 0;
const long interval = 1000;  // Czas oczekiwania w ms

void setup() {
  Serial.begin(9600); // Inicjalizacja portu szeregowego
  pinMode(ledPin, OUTPUT); // Ustawienie pinu diody LED jako wyjścia
  digitalWrite(ledPin, LOW); // Wyłączenie diody na start
  Serial.println("Uruchomiono Arduino.");
}

void loop() {
  // Sprawdzanie, czy dostępne są dane na porcie szeregowym
  if (Serial.available() > 0) {
    String jsonData = Serial.readString(); // Odczyt danych JSON
    Serial.print("Odebrane dane: ");
    Serial.println(jsonData);

    // Przetwarzanie JSON
    StaticJsonDocument<1024> doc;
    DeserializationError error = deserializeJson(doc, jsonData);

    if (error) {
      Serial.print("Błąd przetwarzania JSON: ");
      Serial.println(error.c_str());
      return;
    }

    // Odczytanie wartości value_1
    if (doc.containsKey("value_1")) {
      float value_1 = doc["value_1"];
      Serial.print("Odczytana wartość: ");
      Serial.println(value_1);

      // Sterowanie diodą LED w zależności od wartości
      if (value_1 > 100) {
        digitalWrite(ledPin, HIGH); // Włącz diodę
        Serial.println("Dioda WŁĄCZONA");
      } else {
        digitalWrite(ledPin, LOW); // Wyłącz diodę
        Serial.println("Dioda WYŁĄCZONA");
      }
    } else {
      Serial.println("Brak klucza 'value_1' w danych JSON.");
    }
  }
}

 

Jako, że mam Arduino po kablu USB-> to  w pythonie zrobilem API do czytania danych
 

import serial
import time
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

# Ustawienia portu szeregowego
serial_port = "COM11"  # Zmień na właściwy port, do którego podłączone jest Arduino
baud_rate = 9600

# URL API
api_url = "http://192.168.0.66:5000/api/receive_data"

# Konfiguracja sesji z ponownymi próbami
session = requests.Session()
retries = Retry(total=5, backoff_factor=1, status_forcelist=[500, 502, 503, 504])
session.mount("http://", HTTPAdapter(max_retries=retries))

def main():
    try:
        # Inicjalizacja połączenia szeregowego
        ser = serial.Serial(serial_port, baud_rate, timeout=1)
        print(f"Połączono z Arduino na {serial_port}")

        while True:
            try:
                # Pobierz dane z API z timeoutem i zamykaniem połączenia
                with session.get(api_url, timeout=5) as response:
                    if response.status_code == 200: 
                        json_data = response.json()  # Przetwarzanie odpowiedzi JSON
                        print(f"Otrzymane dane z API: {json_data}")

                        # Wysyłanie danych JSON do Arduino
                        ser.write((str(json_data) + "\n").encode('utf-8'))
                    else:
                        print(f"Błąd API: {response.status_code}")

                time.sleep(1)  # Odczekaj 1 sekundę przed kolejnym żądaniem

            except requests.exceptions.RequestException as e:
                print(f"Błąd połączenia z API: {e}")
                time.sleep(0.01)  # Odczekaj przed kolejną próbą
            except Exception as e:
                print(f"Wystąpił błąd podczas pętli głównej: {e}")
                break

    except KeyboardInterrupt:
        print("Zakończono działanie.")
    except Exception as e:
        print(f"Wystąpił błąd: {e}")
    finally:
        if 'ser' in locals() and ser.is_open:
            ser.close()
            print("Zamknięto port szeregowy.")

if __name__ == "__main__":
    main()

 

 

Działa 🙂

image.thumb.png.0e4564171f687e4ff66cbc4ef280a4b5.png

edit:

dodalem zabezpieczenie do limitu otwartych połączeń sieciowych na określony portm, żeby jego nie zamykał.

Edited by Conrad
  • Like 4
Posted (edited)

U mnie stan prac wygląda tak: 

Nie sądziłem że tak ciężko będzie znaleźć lampki w pamięci.

 

Jedna uwaga. Manometry używają własnej skali - jedna duża kreska na tarczy to 1, 2,3 i tak dalej, a nie wartości prawdziwe.

 

 

 

Przechwytywanie.JPG

main.7z

Edited by JarkPomsky
  • Like 1
Posted
3 godziny temu, JarkPomsky napisał(a):

U mnie stan prac wygląda tak: 

Nie sądziłem że tak ciężko będzie znaleźć lampki w pamięci.

Jedna uwaga. Manometry używają własnej skali - jedna duża kreska na tarczy to 1, 2,3 i tak dalej, a nie wartości prawdziwe.

Thx

Co do nanometrów to wartość rzeczywista podzielona przez 100 na skali manometrów, czyli 4,19 to wartość 0,419

Nie mam silników krokowych na razie, więc tutaj niepoeksperyemntuje, ale na razie działa to co pokazałeś powyżej.

 

  • Like 1
Posted

Stało się to co podejrzewałem.

Najnowszy hotfix pozmieniał strukturę pamięci - dane są teraz w innym miejscu pamięci, więc program jest ślepy.

Jako że jest to zbyt czasochłonne żeby aktualizować i dość trudne projekt porzucam.

Lepiej poczekać na API.

Jeśli jednak ktoś by chciał poszukać na własną rękę to udostępniam kod gdzie można wprowadzić znalezione offsety i skompilować samemu: 

https://pastecode.io/s/r1zcis5s

Wartości manometrów woltomierzów i amperomierzów są typem "float". Lampki typem "int". Trzeba o tym pamiętać i pozmieniać w kodzie odpowiednio.

Wartości szuka się za pomocą Cheat Engine.

Szukając lampek trzeba zaznaczyć "4 Bytes" i szukać odpowiedni 0 dla wyłączonej i 1 dla zapalonej. 

Szukając reszty trzeba zaznaczyć "float" oraz szukać wartości konkretnie wyświetlanej (pod f8).

 

  • Like 1
  • Sad 1
Posted (edited)
18 minut temu, JarkPomsky napisał(a):

Stało się to co podejrzewałem.

Najnowszy hotfix pozmieniał strukturę pamięci - dane są teraz w innym miejscu pamięci, więc program jest ślepy.

Jako że jest to zbyt czasochłonne żeby aktualizować i dość trudne projekt porzucam.

Lepiej poczekać na API.

Jeśli jednak ktoś by chciał poszukać na własną rękę to udostępniam kod gdzie można wprowadzić znalezione offsety i skompilować samemu: 

https://pastecode.io/s/r1zcis5s

Wartości manometrów woltomierzów i amperomierzów są typem "float". Lampki typem "int". Trzeba o tym pamiętać i pozmieniać w kodzie odpowiednio.

Wartości szuka się za pomocą Cheat Engine.

Szukając lampek trzeba zaznaczyć "4 Bytes" i szukać odpowiedni 0 dla wyłączonej i 1 dla zapalonej. 

Szukając reszty trzeba zaznaczyć "float" oraz szukać wartości konkretnie wyświetlanej (pod f8).

 

Też się tego obawiałem, że jak się tak stanie to nie ma sensu tego tak prowadzić. Pokazałeś i udostępniłeś alternatywę, więc ukłony, może pogrzebię w tym temacie, ale chłopaki w SimRail niech obiecają rzadkie aktualizacje 😉

albo udostępnią I/O dla nas, prosimy @uetam 🙂

 

 

 

Edited by Conrad
  • I agree 4
Posted

Dzisiaj pobawilem się tą pamiecią, faktycznie da sie znalezc wartosci, np SHP, czy moment zalaczenia dzwieku dla czuwaka itp, ale po ponownym uruchomieniu SR gubi te dane 😕

Na razie testuje rozwiazanie na zczytywaniu danych rgb danego pixela. W weekand jak uruchomie drukarke pokaze dzialajacy element. 

Na razie mały test:

 

 

 

  • Like 1
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...

Important Information

Terms of Use Privacy Policy